Insert into multiple Tables from CTE´s with Conditions, invalid Identifier - sql

I have a working query and now I want to insert most of it´s data into some tables.
My problem is that I don´t know how to insert into multiple tables at the same time, use it together with CTE´s and the Conditionals.
works:
with join1 as (...),
with join2 as (...),
with join3 as (..),
with relevantData as (use the joins),
select * from relevantData r;
This returns everything I want to have.
Now I want to move the relevantData, depending on some conditions, into different tables.
I have tried:
insert all
when r.column1 is not null then
insert into table1(Signature) values (r.column1,r.column5)
when r.column30 <> 'barney'
insert into table2(Signature) values (r.column8,r.column10,r.column11)
with join1 as (...),
with join2 as (...),
with join3 as (..),
with relevantData as ()
select * from relevantData r;
I have put the insert all as the first line but then the last r.column in my values is always false. ie: when I remove "insert into table2..." then the r.column5 will not be recognized, when I add it again the r.column11 will not be recognized.
However, if I remove this insert stuff again and only select for r.column5 it will be shown.
The error is: ORA-00904 Invalid Identifier

You write only one time with keyword when writing cte's and when you write insert all clause then you only write into keyword not insert into like you did. Syntax goes:
INSERT ALL
WHEN CONDITION_1 THEN
INTO YOUR_TABLE_1 (COLUMN_LIST) VALUES (VALUE_LIST)
WHEN CONDITION_2 THEN
INTO YOUR_TABL_2 (COLUMN_LIST) VALUES (VALUE_LIST)
...
WITH CTE_1 AS (
SELECT STATEMENT
),
CTE_2 AS(
SELECT STATEMENT
)...
SELECT STATEMENT

Related

How to get a key from another table in a insert into... Values SQL statement?

I am not very experienced in SQL statements and I am trying to combine a couple of statements to have less traffic to the db.(and to make sure no other actions can happen inbetween)...
I have two tables:
Table: R_LOTS
a.o. 2 columns: PK_R_LOT and LOTCODE
Table: R_LOTTRACKING
Columns: FK_R_LOT,TIMESTAMP,FK_MAGLOCATIES
I use the statement:
INSERT INTO R_LOTTRACKING (FK_R_LOT,TIMESTAMP,FK_MAGLOCATIES) VALUES (?,CURRENT_TIMESTAMP,?).
On the questionmarks I can fill in the values to send.
However, as you can imagine, I do not have the FK_R_LOT but I have the LOTCODE (of R_LOT).. Of course I can get the FK_R_LOT with a seperate SELECT PK_R_LOT FROM R_LOT WHERE LOTCODE=?; but is there a way to combine these statements?
I have seen some examples but then all information seems to come from the R_LOT table but I could not find a combination of VALUES and SELECT.
Summary:
I know: LOTCODE and FK_MAGLOCATIES
How to combine the statements to insert the row:
INSERT INTO R_LOTTRACKING (FK_R_LOT,TIMESTAMP,FK_MAGLOCATIES) VALUES (?,CURRENT_TIMESTAMP,?)
SELECT PK_R_LOT FROM R_LOT WHERE LOTCODE=?
Use a subquery:
INSERT INTO R_LOTTRACKING ( FK_R_LOT, ... )
VALUES ( (SELECT PK_R_LOT FROM R_LOT WHERE LOTCODE = ?), ... );
or use an insert select:
INSERT INTO R_LOTTRACKING ( FK_R_LOT, ... )
SELECT PK_R_LOT, ... FROM R_LOT WHERE LOTCODE = ?;

Insert into 2 tables with single insert statement

In MSSQL inserting into 2 tables is possible with single insert statement like below(with OUTPUT clause):
insert into Table1(ID1 , Col1)
OUTPUT inserted.ID1, Inserted.Col1
into Table2
values(1,'Col'), (2,'Col2');
Do we have any alternative for this in postgresql? I have tried with below already which is working for me now:
with cte as
(insert into Table1(ID1 , Col1)
values(1,'Col'), (2,'Col2')
returning *)
insert into Table2 select * from cte ;
Please let me know if we have any other alternative. I know about trigger also, but I don't want to use it here.

Saving results from RETURNING in separate variables

Problem
Say I have the following insert statement:
insert into table_1 (...) values (...), (...), (...);
Assuming I know those 3 rows will be correctly inserted (no clause is violated), how can I fetch the id field of each inserted row into a separate variabile in order for me to use it in the rest of the .sql script?
What I tried
I've read about returning which would presumably translate into:
insert into table_1 (...) values (...), (...), (...) returning id;
I've also read about with (Common Table Expressions) which could "save" the result of returning into a table for later use in the following insert statements;
but it appears that I would then have to get the ids as select id from temp_table associating some kind of selector to distinguish between each 3 rows.
Question
Is there a way to get the ids of each inserted row to later use them, separately, in a different insert statement?
You could use three CTEs:
with i1 as (
insert into table_1 (...) values (...)returning id
),
i2 as (
insert into table_1 (...) values (...) returning id
),
i3 as (
insert into table_1 (...) values (...) returning id
)
insert . . .;
This doesn't put the values into three variables. It does put them in three separate CTEs so each can be referred to individually.

SQL. When I trying to do something like "INSERT INTO Table VALUES(x1,x2,x3) - can the x1 x2 x3 be sql queries, like SELECT <...>

I want to do something like this:
QSqlQuery q;
q.prepare("insert into Norm values(select from Disc id_disc WHERE name_disc=?, select from Spec code_spec WHERE name_spec=?,?");
q.addBindValue(MainModel->data(MainModel->index(MainModel->rowCount()-1, 1)).toString());
q.addBindValue(ui->comboBox->currentText());
q.addBindValue(MainModel->data(MainModel->index(MainModel->rowCount()-1, 2)).toString());
q.exec();
But it's not working. Surely for someone obviously where is the error and maybe he tells me how to do it right.
First of all your you have done spelling mistake. Its "INSERT" not "INCERT"
And yes we can insert SELECT query inside INSERT query.
eg:
INSERT INTO table2
(column_name(s))
SELECT column_name(s)
FROM table1;
INSERT ... SELECT ... is used when you want to insert multiple records, or when most values to be inserted come from the same record.
If you want to insert one record with values coming from several tables, you can use subqueries like you tried to do, but you have to use the correct syntax:
scalar subqueries must be written inside parentheses, and you must write the SELECT correctly as SELECT value FROM table:
INSERT INTO Norm
VALUES ((SELECT id_disc FROM Disc WHERE name_disc = ?),
(SELECT code_spec FROM Spec WHERE name_spec = ?),
?)
If you want data from two tables, you must first write a query which return pretended data - using JOIN, UNION, subqueries, ...
Then, just do
INSERT INTO target_table SELECT ...

Storing Multiple Insert IDs

After scouring the site (and others...), I cannot find an example of an insert command allowing me to store the "RETURNING" values to a table, CTE, etc. This is what I'd like to do:
WITH insert_rows AS (
INSERT INTO employers (column1, column2, insert_date)
SELECT distinct tc.column1, 'any text', now()
FROM _tmp_employer_updates tc
LEFT JOIN employers e ON e.column1 = tc.column1
WHERE e.column1 IS NULL -- Only insert non-existing employer names
RETURNING employer.row_uuid, employer.column1, employer.column2;
)
SELECT * FROM insert_rows; -- table of returning values
Is there anyway to get an insert command to store it's "returning" values to a table using a CTE? When I try the example above I get:
ERROR: syntax error at or near "INSERT"
LINE 1: ... _tmp_inserted_employers AS WITH insert_rows AS ( INSERT INT...
Thanks in advance...
Remove ; after returning ..., remove alias employer before columns in returning (or change it to employers). Otherwise your query looks good.
Here's an example on sql fiddle.