Slick/Oracle PLAIN SQL Get auto generated ID after insert - oracle

I am trying to run a query via Slick in Scala that will insert a record into an Oracle db and return the auto generated ID as the result. I see that this is possible using Slick's syntax but is this possible using a plain SQL query? With below code I can only get a return value of -1.
val name = "Bob"
db.run(sql"""DECLARE NEW_PERSON_ID;
BEGIN
INSERT INTO TB_PEOPLE (ID, NAME)
VALUES(SEQ_PEOPLE.NEXTVAL, $name)
RETURNING ID INTO NEW_PERSON_ID;
END;""".as[Int])

It seems that Slick doesn't support output parameters so using Oracle's returning syntax won't work. A workaround I found is to first generate an ID and then insert using that ID (requires 2 queries). The queries are wrapped in a transaction.
val name = "Bob"
val action = for {
newPersonId <- sql"""SELECT SEQ_PEOPLE.NEXTVAL FROM DUAL""".as[Int]
_ <- sqlu"""INSERT INTO TB_PEOPLE (ID, NAME) VALUES ($newPersonId, $name)"""
}
db.run(action.transactionally)

Related

how to update select column in Spring data?

Please check the below query I am trying to update a row by the composite key
my key combination is like:
int id
int versionId
String languageId
and query is:
#Transactional
#Modifying
#Query("update languageEntity l set l.language = :language where l.languageId = :languageId")
int UpdateProcessLanguage(#Param("language ") String processDesTranslation, #Param("languageId ") UserLanguageId languageId);
I am not getting any exception. function is returning 0, means no row effected.
please check what is worng.
It's hard to say without knowing the data. As a first step I would log the generated SQL statements (see how to log sql statements in spring-boot) and check if they look right.
Why you dont wan't to use save() method for that? Just change language property on your object and pass it to the save method. It will update the row.

jruby jdbc how to get id of inserted row

I have insert query that works, but I can't get ID of created row in return. How can I achieve that? having this:
conn = Java::JavaSql::DriverManager.getConnection(url)
st = conn.create_statement
rs = st.execute_update(query)
How can I get id?
more of a JDBC question that depends on the DB/driver used.
generally st.generated_keys gives you a result set of the IDs
also read: How to get the insert ID in JDBC?

Linq to entity update query not updating the table

Its just a simple Linq to Entity update query i tried with the following code but it doesn't update the "User" column in the DB.
Its not even throwing any exception also,please some one point me what am missing here.
MyEntities db = new MyEntities ();
var query = from SEVTs in db.SEVTs
where SESID == "4747747"
select SEVTs;
foreach (var SEVTs in query) {
SEVTs.USER = "Test";
}
db.SaveChanges();
Quite interesting, when i try the follwing query in the sql server its not update the record
update Schedwin.SEVT
set
USER3='Test'
Where
SESID='4747747' // here i pass the value as a string
SESID data type is CHAR and its a primary key. if i pass the value as SESID=4747747 then it update that record.
Please ignore my question.
Here what i missed my input value SESID == "4747747" //this have whitespace that's why it didn't updated that particular record.
Thanks All
You are nor modifying SEVTs.USER, but some local variable.
(BTW: create a context in a using construct)

How to get next id in GRAILS?

I need to get the next available id in a sequence, using GORM or native query.
How can I do this?
I'm using oracle.
UPDATE:
I need this value BEFORE insert, because my row will use this value.
I have table called IMAGE, with column FILE_NAME, like this:
- ID | FILE_NAME
- 123 | foo_bar_123.png
- 124 | xxx_yyy_124.png
Tks a lot.
Why do you need the value before the insert? Could you get the information as part of the insert using the RETURNING clause, i.e.
INSERT INTO table_name( id, file_name )
VALUES( some_sequence.nextval, <<bind variable>> )
RETURNING id INTO <<bind variable>>
Or access it after the insert using
SELECT sequence_name.currval
FROM dual
The currval of a sequence returns the most recent value of the sequence produced in the current session so it is actually thread-safe. Since sequences are designed to provide numbers in a highly concurrent environment, you cannot in general find out what the nextval is going to be unless you actually fetch the nextval. Even if you could, there is no guarantee that another thread won't come along and get the value you peeked at before your INSERT took place so it wouldn't be safe to peek at the nextval in a multi-user environment.
I adapted #Cave tips.
So, my solution is:
Change my mapping from:
class Image {
...
id column: "ID", generator: "sequence", params: [sequence:"MY_SEQUENCE"]
...
}
to:
class Image {
...
id column: "ID", generator: "assigned"
...
}
And set id mannualy using this:
def getLastImageId(){
def sql = "SELECT MY_SEQUENCE.nextval FROM dual"
def query = sessionFactory.currentSession.createSQLQuery(sql);
def result = query.list()
return result[0]
}
...
newImage.id = getLastImageId()
newImage.fileName = "foo_bar_${newImage.id}.png"

Linq Contains issue: cannot formulate the equivalent of 'WHERE IN' query

In the table ReservationWorkerPeriods there are records of all workers that are planned to work on a given period on any possible machine.
The additional table WorkerOnMachineOnConstructionSite contains columns workerId, MachineId and ConstructionSiteId.
From the table ReservationWorkerPeriods I would like to retrieve just workers who work on selected machine.
In order to retrieve just relevant records from WorkerOnMachineOnConstructionSite table I have written the following code:
var relevantWorkerOnMachineOnConstructionSite = (from cswm in currentConstructionSiteSchedule.ContrustionSiteWorkerOnMachine
where cswm.MachineId == machineId
select cswm).ToList();
workerOnMachineOnConstructionSite = relevantWorkerOnMachineOnConstructionSite as List<ContrustionSiteWorkerOnMachine>;
These records are also used in the application so I don't want to bypass the above code even if is possible to directly retrieve just workerPeriods for workers who work on selected machine. Anyway I haven't figured out how it is possible to retrieve the relevant workerPeriods once we know which userIDs are relevant.
I have tried the following code:
var userIDs = from w in workerOnMachineOnConstructionSite select new {w.WorkerId};
List<ReservationWorkerPeriods> workerPeriods = currentConstructionSiteSchedule.ReservationWorkerPeriods.ToList();
allocatedWorkers = workerPeriods.Where(wp => userIDs.Contains(wp.WorkerId));
but it seems to be incorrect and don't know how to fix it. Does anyone know what is the problem and how it is possible to retrieve just records which contain userIDs from the list?
Currently, you are constructing an anonymous object on the fly, with one property. You'll want to grab the id directly with (note the missing curly braces):
var userIDs = from w in workerOnMachineOnConstructionSite select w.WorkerId;
Also, in such cases, don't call ToList on it - the variable userIDs just contains the query, not the result. If you use that variable in a further query, the provider can translate it to a single sql query.

Resources