ibatis/Oracle - SELECT query inside INSERT is failing - sql

I'm trying to do an Insert operation using iBatis.
INSERT INTO SCHEMA.TABLE
(FIELD1,
FIELD2,
FIELD3)
VALUES
(#field1#,
(SELECT
ANOTHER_FIELD
FROM
SCHEMA.TABLE
WHERE
FIELD4= #field2#),
#field2#)
The inner select query always fails and returns NULL. But if I substitute #field2# with the actual value only in the inner query, it works fine.
Why is iBatis not substituting fieldvalues in the innerqueries?
Any ideas?

The following way using a single sub-query and omitting the VALUES keyword would work with Oracle, please try with iBatis:
INSERT INTO SCHEMA.TABLE
(FIELD1,
FIELD2,
FIELD3)
(
SELECT
#field1#,
ANOTHER_FIELD,
#field2#
FROM
SCHEMA.TABLE
WHERE
FIELD4= #field2#
)

That syntax is invalid for Oracle. Try the following:
INSERT INTO SCHEMA.TABLE
(FIELD1,
FIELD2,
FIELD3)
SELECT
#field1#,
ANOTHER_FIELD,
#field2#
FROM
SCHEMA.TABLE
WHERE
FIELD4= #field2#

Related

Insert multiple rows for each of a result set?

my google-fu is failing me.
I'm trying to do the following in a more automatic way:
1) select a set of fields from 1 table
select ACCT_ID from MASTER_ACCT where CUST_NBR like '%ABC';
2) use the results of that in a multiple row insert
// for each ACCT_ID in (1)
insert into TOGGLES (FIELD1, FIELD2, FIELD3)
values('abc', '123', ACCT_ID[i]);
Is there a way to execute the 2nd statement for ACCT_ID[i] in each of the ACCT_ID results from the 1st statement?
You would use an INSERT INTO...SELECT statement:
INSERT INTO toggles (field1, field2, field3)
SELECT 'abc', '123', acct_id
FROM master_acct
WHERE cust_nbr LIKE '%ABC';
You might use the below syntax
INSERT INTO target_table[()] SELECT ... FROM ...;
find this link for more details.

insert Default value For a column while inserting data from other table

I am facing an issue when I am inserting data into table1 by selecting data from table2
like
INSERT INTO table1
SELECT * FROM table2
So there is a column in both table like field1 for which value is null in table2.
But in table I have set the default value for field1
after executing ,
INSERT INTO table1
SELECT * FROM table2
I am having null value for field1 insted of getting default value of it what i set.
You Can Specify the column names and then set the value in your Select Statement
INSERT INTO table1 (field1, field2, field3, ...)
SELECT field1,
CASE WHEN field2 IS NOT NULL THEN field2
ELSE 'Your_default_value' END ,
field3, ...
FROM table2
INSERT INTO table1 (field2, field3, ...)
SELECT field2, field3, ...
FROM table2
You just skip the column for which default value oyu want to use and it will be automatically populated with default.
Interesting, One way to achieve this is use of CASE EXPRESSION, Assuming that field2 is column which you wants to put default value
INSERT INTO TableName1 (field1, field2, field3, ...)
SELECT field1, CASE WHEN field2 IS NULL THEN 'DefaultValue' ELSE field2 END, field3, ...
FROM TableName2
Try using NVL
INSERT INTO TableName1 (field1, field2, field3, ...)
SELECT field1, NVL(field2,'Your Default Value'), field3, ...
FROM TableName2
For example:
INSERT INTO DESTINATION_TABLE(A, B, C, D, E, F)
SELECT W, X, Y, 'Some custom value', CASE WHEN Z IS NULL THEN 'Some other value' ELSE Z
FROM SOURCE_TABLE
WHERE ....
Any time you want to replace a null value, use COALESCE. COALESCE is available in both Oracle and SQL Server, it doesn't evaluate arguments unless needed (NVL always evaluates the second argument), and it is simpler than a case statement:
Insert into table1(field1, field2)
select field1, coalesce(field2, field3, field4, 'novalue') from table2;
One big difference between NVL and COALESCE, if the second argument has side effects, you could come up with different results.

How can I stop a postgres table from having duplicate record and instead writing the duplicate records in another table

How can I stop a Postgres table from having duplicate record and instead writing the duplicate records in another table. I want to copy data from “table1” to “table2” and if there is any duplicate data in “table1” then it should be copied to “duplicates” instead of “table2”.
The problem is:
Creating a unique key on table2 stops the data insertion with error
ERROR: duplicate key value violates unique constraint
unlike in MySQL where an IGNORE command can be used.
Creating a rule on table2 does not help for a check per ROW basis.
CREATE RULE "copy_dup" AS ON INSERT TO "table2"
WHERE EXISTS
(SELECT 1 FROM table2 WHERE (field1, field2, field3) =
(NEW.field1, NEW.field2, NEW.field3))
DO INSTEAD INSERT INTO duplicates
(field1, field2, field3)
VALUES
(NEW.field1, NEW.field2, NEW.field3);
INSERT INTO "table2"
(field1, field2, field3)
SELECT
field1, field2, field3 FROM table1;
Creating a trigger is giving syntax error at when:
CREATE FUNCTION data_insert_table2()
RETURNS void AS
$$
BEGIN
INSERT INTO table2(field1, field2, field3)
SELECT field1, field2, field3
FROM table1;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER ignore_dup
BEFORE INSERT ON table2
FOR EACH ROW
WHEN (OLD.* IS DISTINCT FROM NEW.*)
EXECUTE PROCEDURE data_insert_table2();
ERROR: syntax error at or near "WHEN"
Does trigger not support WHEN clause ?
I am not very intimate with Postgres. Can anyone help?
Both table1 and table2 have primary key on their serial_id which is not being copied from one table to another.
I am not sure whether this function works as trigger fails at WHEN.
Problem
Your trigger fails for (at least) this reason: the special variable OLD is not defined for INSERT triggers. There is no "old" row, like in DELETE or UPDATE triggers.
Permanent solution with trigger
Otherwise a trigger solution should work just fine. Building on your updated question:
CREATE FUNCTION data_insert_table2()
RETURNS trigger AS
$func$
BEGIN
--
INSERT INTO dupe(field1, field2, field3) -- insert into other table
SELECT NEW.field1, NEW.field2, NEW.field3
WHERE EXISTS ( -- if dupe is already in table2
SELECT 1 FROM table2
WHERE (field1, field2, field3) = (NEW.field1, NEW.field2, NEW.field3)
);
IF FOUND THEN -- only if the above wrote to the dupe table ..
RETURN NULL; -- .. cancel original INSERT
END IF;
RETURN NEW; -- else proceed normally
END;
$func$ LANGUAGE plpgsql;
CREATE TRIGGER ignore_dup
BEFORE INSERT ON table2
FOR EACH ROW -- no WHEN condition!
EXECUTE PROCEDURE data_insert_table2();
One-time operation
For a one-time operation I would go with a query using data-modifying CTEs, though (Postgres 9.1 or later):
WITH sel AS (
SELECT t.field1, t.field2, t.field3
FROM (
SELECT DISTINCT ON (field1, field2, field3) -- fold duplicates in source
pk_col, field1, field2, field3
FROM table1
ORDER BY field1, field2, field3, pk_col -- take "first" row per set
) t
LEFT JOIN table2 t2 USING (field1, field2, field3)
WHERE t2.field1 IS NULL -- except rows in table2
)
, ins1 AS (
INSERT INTO table2 (field1, field2, field3)
SELECT field1, field2, field3
FROM sel
)
INSERT INTO dupes (field1, field2, field3)
SELECT t.field1, t.field2, t.field3
FROM table1 t
LEFT JOIN sel USING (pk_col)
WHERE sel.pk_col IS NULL;
Combine that with a UNIQUE constraint on table2 to make sure your requirements are met.
Note that two columns holding NULL ate not considered the same. If you disagree with this standard SQL definition, you have to define all columns NOT NULL to make this work.
This operation is prone to race conditions. If multiple clients might be running this concurrently, you'd need exclusive locks. But it looks like a single-user job.

How to insert rows with structure from one table to another table?

What is the query in SQL Server to insert rows with structure from one table to another table?
A couple ways
SELECT INTO
SELECT
field1,
field2,
...
INTO Table1
FROM Table2
INSERT INTO
INSERT INTO Table1
field1,
field2,
...
SELECT
field1,
field2,
...
FROM Table2
Sounds like you want something like this:
INSERT INTO DestTable (Column1,COlumn2)
SELECT Column1, Column2
FROM SourceTable
Here is the documentation for the INSERT...EXECUTE statement that will allow you to do what you need.

Copy record to another table adding fields

I have 2 tables:
tab1 (field1, field2, field3)
tab2 (field1, field2,field3, field4)
I want to copy a record from tab1 to tab2 taking all the fields and adding a value for field4.
How can I select field1, field2 and field3 from tab2 and also add a value? I know that SELECT and VALUES in a INSERT query are mutually exclusive.
Thanks in advance.
Gustavo.
I don't know Oracle, but in Ms SQL it works like this:
insert into tab2 (field1, field2, field3, field4)
select field1, field2, field3, 'New Value' from tab1