JOOQ: extract value from Field - sequence

I have a table with PK and another column for other id. In some cases i need to insert record with equal values in both columns. For primary key values i'm using sequence, which gives a Field<Long> from Sequences.MY_SEQ.nextval().
How can i extract value from a Field<Long> for guaranteed insert same ids in both columns? Using Field<Long> in insert clause generates 2 different ids in columns.

Here is the solution:
Long id = dsl.select(Sequences.MY_SEQ.nextval()).fetchOne().value1();

Your own solution works, of course, but it will generate two round trips to the database. One for fetching the sequence value and another one for the insert. If that's not a problem, perfect. Otherwise, you can still do it in one single query using INSERT .. SELECT:
In SQL:
(using Oracle syntax. Your SQL syntax may vary...)
INSERT INTO my_table (col1, col2, val)
SELECT t.id, t.id, 'abc'
FROM (
SELECT my_seq.nextval AS id
FROM dual
) t
With jOOQ
Table<?> t = table(select(MY_SEQ.nextval().as("id"))).as("t");
dsl.insertInto(MY_TABLE)
.columns(MY_TABLE.COL1, MY_TABLE.COL2, MY_TABLE.VAL)
.select(
select(t.field("id"), t.field("id"), val("abc"))
.from(t))
.execute();

Related

Generate insert column based on select columns

I have a scenario, where 100's of select statements sql's are in one metadata table or some text file.
Need to insert all sql results into one specific table. (master table has col1, col2,col3 .... 200columns )
problem im facing(ORA-00947) is every select statement has different number of columns.
.. i need to generate INSERT PART.
CASE 1 : INSERT INTO (COL1,COL2,COL3) <<this select part comes from file/variable>>
CASE 2 : INSERT INTO (COL1) <<this select part comes from file/variable>>
CASE 3 : INSERT INTO (COL1) <<this select part comes from file/variable>>
have to figure out how many columns are in select part then generate INSERT part.
.
Thought of create as select but problem is some select statement has max(col) without alias so it will fail.
This is too long for a comment.
If you are storing SQL in a table, then you are constructing your query dynamically. So, update the table and list the columns that you want.
You could then construct the inserts as :
insert into master_table (<column list here>)
<select here>;
Both the select and column list would come from the table.
By far the easiest is to create a view for each SELECT statement. Then you can query the USER_TAB_COLUMNS view on the view name and get the column names.
Best regards,
Stew Ashton

SQL Insert existing/duplicate row into table but change only one column value?

I have Audit table with more than 50 columns and need to insert desired row (duplicate) by changing just one column value (column CreatedDate, set value to GETDATE()). I know this can be achieved by INSERT INTO SELECT * FROM but as there is more han 50 columns, code would seem messy:
INSERT INTO Audit_Table (Col1, Col2, .....CreatedDate, ......, Col50, ...ColN)
SELECT (Col1, Col2, .....GETDATE(), ......, Col50, ...ColN) FROM Audit_Table
WHERE Audit_Table.Id = Desired_Id
If i shouldn't change CreatedDate column value, it would be very simple:
INSERT INTO Audit_Table SELECT * FROM Audit_Table WHERE Audit_Table.ID = Desired_Id
Is there any other way to duplicate row and change only one/desired column value?
You can insert the record into a temporary table, update the CreatedDate column to GETDATE(), then insert it into the Audit_Table.
No. There is no way to say * except column_foo in SQL.
The workaround would be to generate the
SELECT
col1
, col2
, [...]
, coln
FROM foo;
statement (or parts of it) by querying the database's system catalogue for the column names in their order. There is always a table with all tables and a table with all columns.
Then, make sure you put the necessary commas in the right place (or remove them where you don't need them, or generate the comma in all rows of the report but the first - by using the ROW_NUMBER() OLAP function and evaluating whether it returns 1 or something else). Finally, edit the right date column, by replacing it with CURRENT_DATE or whatever your database uses for the current day.
Good luck -
Marco
You can build upon your existing idea. Just duplicate the row (I assume, you have an auto-incrementing primary key column) and then in a separate query update the time i.e.
Do this :
INSERT INTO Audit_Table SELECT * FROM Audit_Table WHERE Audit_Table.ID = Desired_Id
And then :
UPDATE Audit_Table SET CreatedDate = GETDATE() WHERE primaryKeyID = newPrimaryKeyID
Hope this helps!!!
try below as reference
you can use below statement to copy the all rows,
mysql> insert into newstudent select * from students;
you can use below statement to copy the specific row from table,
mysql> insert into newstudent
-> select id, name, age, address
-> from students
-> where
-> id = 1248;
you can use below statement to copy the either of the row from table,
mysql> insert into newstudent
-> select id, name, age, address
-> from students
-> where
-> id = 1248 or id=1249;
use limit clause also along with this

SELECT * FROM NEW TABLE equivalent in Postgres

In DB2 I can do a command that looks like this to retrieve information from the inserted row:
SELECT *
FROM NEW TABLE (
INSERT INTO phone_book
VALUES ( 'Peter Doe','555-2323' )
) AS t
How do I do that in Postgres?
There are way to retrieve a sequence, but I need to retrieve arbitrary columns.
My desire to merge a select with the insert is for performance reasons. This way I only need to execute one statement to insert values and select values from the insert. The values that are inserted come from a subselect rather than a values clause. I only need to insert 1 row.
That sample code was lifted from Wikipedia Insert Article
A plain INSERT ... RETURNING ... does the job and delivers best performance.
A CTE is not necessary.
INSERT INTO phone_book (name, number)
VALUES ( 'Peter Doe','555-2323' )
RETURNING * -- or just phonebook_id, if that's all you need
Aside: In most cases it's advisable to add a target list.
The Wikipedia page you quoted already has the same advice:
Using an INSERT statement with RETURNING clause for PostgreSQL (since
8.2). The returned list is identical to the result of a SELECT.
PostgreSQL supports this kind of behavior through a returning clause in a common table expression. You generally shouldn't assume that something like this will improve performance simply because you're executing one statement instead of two. Use EXPLAIN to measure performance.
create table test (
test_id serial primary key,
col1 integer
);
with inserted_rows as (
insert into test (c1) values (3)
returning *
)
select * from inserted_rows;
test_id col1
--
1 3
Docs

SQL How to insert null value

I want to insert data into one table from another table. In some of the columns I don't have data, so I want to set column to null. I don't know how I should do this?
This is the SQL:
INSERT INTO _21Appoint(
PCUCODE,PID,SEQ,
DATE_SERV,APDATE,
APTYPE,APDIAG,D_UPDATE,CID
) SELECT (
NULL,NULL,NULL,
treatment_date,appointment_date,
typeap_id,appointment_id,NULL,patient_id
) FROM cmu_treatment,cmu_appointment
WHERE cmu_treatment.treatment_id LIKE cmu_appointment.treatment_id;
Your insert is essentially correct. Just don't put the column list in parentheses:
INSERT INTO _21Appoint
(PCUCODE,PID,SEQ,DATE_SERV,APDATE,APTYPE,APDIAG,D_UPDATE,CID)
SELECT NULL,NULL,NULL,treatment_date,appointment_date,typeap_id,appointment_id,NULL,patient_id
FROM cmu_treatment,cmu_appointment
WHERE cmu_treatment.treatment_id LIKE cmu_appointment.treatment_id;
In Postgres (unlike other DBMS) putting a column list in parentheses makes the result a single "record", rather then individual columns. And therefore the select only returns a single column, not multiples and thus it doesn't match the column list for the insert
another option is to simply leave out the columns completely:
INSERT INTO _21Appoint
(DATE_SERV,APDATE,APTYPE,APDIAG,CID)
SELECT treatment_date,appointment_date,typeap_id,appointment_id,patient_id
FROM cmu_treatment,cmu_appointment
WHERE cmu_treatment.treatment_id LIKE cmu_appointment.treatment_id;

Sqlite - SELECT or INSERT and SELECT in one statement

I'm trying to avoid writing separate SQL queries to achieve the following scenario:
I have a Table called Values:
Values:
id INT (PK)
data TEXT
I would like to check if certain data exists in the table, and if it does, return its id, otherwise insert it and return its id.
The (very) naive way would be:
select id from Values where data = "SOME_DATA";
if id is not null, take it.
if id is null then:
insert into Values(data) values("SOME_DATA");
and then select it again to see its id or use the returned id.
I am trying to make the above functionality in one line.
I think I'm getting close, but I couldn't make it yet:
So far I got this:
select id from Values where data=(COALESCE((select data from Values where data="SOME_DATA"), (insert into Values(data) values("SOME_DATA"));
I'm trying to take advantage of the fact that the second select will return null and then the second argument to COALESCE will be returned. No success so far. What am I missing?
Your command does not work because in SQL, INSERT does not return a value.
If you have a unique constraint/index on the data column, you can use that to prevent duplicates if you blindly insert the value; this uses SQLite's INSERT OR IGNORE extension:
INSERT OR IGNORE INTO "Values"(data) VALUES('SOME_DATE');
SELECT id FROM "Values" WHERE data = 'SOME_DATA';