I am trying to create a db2 trigger with the following functionality ...
When a record is inserted / updated into Table1, insert / update that same record into Table2. The catch is, Table1 has 11 columns, and Table2 has 5 columns. The 5 columns in Table2 are the exact same as 5 of the columns in Table1, however, since Table1 has an additional 6 columns, how will the Trigger know which 5 of the 11 specific columns I would like to Insert / Update into Table2?
For example:
Table1
MasterID
SubMasterID
Price
Location
Type
Status
Contact First Name
Contact Last Name
Contact Email
Contact State
Contact Zip
Table2
MasterID
SubMasterID
Price
Location
Type
From the example above, After an Insert / Update into Table1, I would like to insert / update that same record into Table2, however with only the 5 columns in Table2 (meaning MasterID, SubMasterID, Price, Location, Type).
Is this actually possible with a trigger in Db2?
Or would anyone recommend writing a piece of code instead?
Thanks! Any help is appreciated.
I've tried creating a trigger (untested) like so,
CREATE OR REPLACE TRIGGER "SCHEMA1"."TABLE1_TABLE2_INSERT" AFTER
INSERT
ON
SCHEMA1.TABLE1 REFERENCING NEW AS A
FOR EACH ROW MODE DB2SQL BEGIN ATOMIC
INSERT
INTO
SCHEMA2.TABLE2
(
"MasterID",
"SubMasterID",
"Price",
"Location",
"Type"
)
VALUES
(
a.MasterID,
a.SubMasterID,
a.Price,
a.Location,
a.Type
);
END
However, I am unsure how this trigger can specifically identify the specific columns from Table1 to insert / update into Table2.
Related
I want to insert into table1 multiple rows from table2. The problem is that I have some fields in table1 that I want to compute, and some rows that I want to select from table2. For example something like this:
insert into table1 (id, selectField1, selectField2, constant)
values ((gen_random_uuid()), (select superField1 from table2), (select superField2 from table2), 'test');
So the logic is to select superField1 and superField2 from all the rows in the table2 and insert them into table1 with constant value test and generated uids. superField1 and superField2 should be from the same row in table2 when inserting in table1. How can I achieve something like this using liquibase?
P.S: I'm using <sql> tag since it's easier to implement using SQL than using XML changeset, but if you know how to do it in XML that would be appreciated too, but just in SQL will be enough too. DBMS is postgres.
Don't use the VALUES clause if the source is a SELECT statement:
insert into table1 (id, selectField1, selectField2, constant)
select gen_random_uuid(), superField1, superField2, 'test'
from table2;
ّ am trying to insert multiple records got from the join table to another table user_to_property. In the user_to_property table user_to_property_id is primary, not null it is not autoincrementing. So I am trying to add user_to_property_id manually by an increment of 1.
WITH selectedData AS
( -- selection of the data that needs to be inserted
SELECT t2.user_id as userId
FROM property_lines t1
INNER JOIN user t2 ON t1.account_id = t2.account_id
)
INSERT INTO user_to_property (user_to_property_id, user_id, property_id, created_date)
VALUES ((SELECT MAX( user_to_property_id )+1 FROM user_to_property),(SELECT
selectedData.userId
FROM selectedData),3,now());
The above query gives me the below error:
ERROR: more than one row returned by a subquery used as an expression
How to insert multiple records to a table from the join of other tables? where the user_to_property table contains a unique record for the same user-id and property_id there should be only 1 record.
Typically for Insert you use either values or select. The structure values( select...) often (generally?) just causes more trouble than it worth, and it is never necessary. You can always select a constant or an expression. In this case convert to just select. For generating your ID get the max value from your table and then just add the row_number that you are inserting: (see demo)
insert into user_to_property(user_to_property_id
, user_id
, property_id
, created
)
with start_with(current_max_id) as
( select max(user_to_property_id) from user_to_property )
select current_max_id + id_incr, user_id, 3, now()
from (
select t2.user_id, row_number() over() id_incr
from property_lines t1
join users t2 on t1.account_id = t2.account_id
) js
join start_with on true;
A couple notes:
DO NOT use user for table name, or any other object name. It is a
documented reserved word by both Postgres and SQL standard (and has
been since Postgres v7.1 and the SQL 92 Standard at lest).
You really should create another column or change the column type
user_to_property_id to auto-generated. Using Max()+1, or
anything based on that idea, is a virtual guarantee you will generate
duplicate keys. Much to the amusement of users and developers alike.
What happens in an MVCC when 2 users run the query concurrently.
I'm having an issue with a simple update statement. I'm new to postgresql and I'm still stuck on MS Sql Server syntax.
What I want to do is to update all records from table1 which are not present / don't exist in table2. Table1 and Table2 are having an 1 to 1 relation. The join column is "colx" from my example
On Ms SQL Server I would have something like this:
UPDATE table1 set col1='some value' from table1 t1 LEFT JOIN table2 t2 on t1.colx=t2.colx WHERE t2.colx IS NULL
or
UPDATE table1 set col1='some value' from table1 t1 where not exists (select 1 from table2 t2 where t1.colx=t2.colx)
My issue is when performing the same on PostgreSql it updates all records from table1, not only the records matching the condition (e.g. I was expecting 4 records to be updated, but all records from table1 are updated instead).
I checked using a select statement the join condition for all possible approaches and I have the expected result (e.g. 4 records).
Is there anything I'm missing?
Your question is not very clear about the requirement.
What I understood is you want to update the value of col1 in table1 for those records which are not present in the table2.
You can try it this way in Postgresql:
UPDATE table1 t1 set col1='some value' where not exists(select 1 from table2 where colx=t1.colx)
DEMO
I've been looking for an answer to this question for a few days and can't find anything referencing this specific issue.
First of all, should it work if I want to use an INSERT INTO SELECT statement to copy over rows of a table, back into the same table but with new id's and 1 of the column modified?
Example:
INSERT INTO TABLE_A (column1, column2, column3) SELECT column1, 'value to change', column3 from TABLE_A where column 2 = 'original value';
When I try this on a DB2 database, I'm getting the following error:
INVALID MULTIPLE-ROW INSERT. SQLCODE=-533, SQLSTATE=21501, DRIVER=4.18.60
If I run the same statement but I put a specific ID to return in the select statement, ensuring only 1 row is returned, then the statement works. But that goes against what I'm trying to do which is copy multiple rows from the same table into itself, while updating a specific column to a new value.
Thanks everyone!
It works fine for me without error on Db2 11.1.4.0
CREATE TABLE TABLE_A( column1 int , column2 varchar(16), column3 int)
INSERT INTO TABLE_A values (1,'original value',3)
INSERT INTO TABLE_A (column1, column2, column3)
SELECT column1, 'value to change', column3 from TABLE_A where column2 = 'original value'
SELECT * FROM TABLE_A
returns
COLUMN1|COLUMN2 |COLUMN3
-------|---------------|-------
1|original value | 3
1|value to change| 3
maybe there is something you are not telling us....
You don't mention your platform and version, but the docs seems pretty clear..
IBM LUW 11.5
A multiple-row INSERT into a self-referencing table is invalid.
First google results
An INSERT operation with a subselect attempted to insert multiple rows
into a self-referencing table. The subselect of the INSERT operation
should return no more than one row of data. System action: The INSERT
statement cannot be executed. The contents of the object table are
unchanged. Programmer response: Examine the search condition of the
subselect to make sure that no more than one row of data is selected.
EDIT You've apparently got a self-referencing constraint on the table. Ex: EMPLOYEES table with a MANAGER column defined as a FK self-referencing back to the EMPLOYEES table.
Db2 simply doesn't support what you are trying to do.
You need to a temporary table to hold the modified rows.
Optionally, assuming that your table has a primary key, try using the MERGE statement instead.
I am new to postgresql (and databases in general) and was hoping to get some pointers on improving the efficiency of the following statement.
I am inserting data from one table to another, and do not want to insert duplicate values. I have a rid (unique identifier in each table) that are indexed and are Primary Keys.
I am currently using the following statement:
INSERT INTO table1 SELECT * FROM table2 WHERE rid NOT IN (SELECT rid FROM table1).
As of now the table one is 200,000 records, table2 is 20,000 records. Table1 is going to keep growing (probably to around 2,000,000) and table2 will stay around 20,000 records. As of now the statement takes about 15 minutes to run. I am concerned that as Table1 grows this is going to take way to long. Any suggestions?
This should be more efficient than your current query:
INSERT INTO table1
SELECT *
FROM table2
WHERE NOT EXISTS (
SELECT 1 FROM table1 WHERE table1.rid = table2.rid
);
insert into table1
select t2.*
from
table2 t2
left join
table1 t1 on t1.rid = t2.rid
where t1.rid is null