I have 2 tables Table1 and Table2 that have the following identical schema:
Table1 (id int, lastModifiedDate datetime)
Table2 (id int, lastModifiedDate datetime)
Table1 is the source table, Table2 is the target table.
I need in only one query to execute the following scenario:
if Table1.id = Table2.id and Table1.lastModifiedDate = Table2.lastModifiedDate then don't do anything.
elseif Table1.id = Table2.id and Table1.lastModifiedDate <> Table2.lastModifiedDate then we have to delete from Table2 all row with this id and then we have to insert into it the matching row
I need also to insert into Table2 id values present in Table1 and not present in Table2
To summarize I need to do something like the following query (which has an incorrect syntax):
MERGE INTO Table2 AS target
USING (SELECT id, lastModifiedDate FROM Table1) AS source ON Source.id = target.id
WHEN NOT MATCHED BY TARGET
THEN INSERT(id,lastModifiedDate) VALUES(source.id,source.lastModifiedDate)
WHEN MATCHED AND Source.lastModifiedDate <> target.lastModifiedDate
THEN Delete
WHEN MATCHED AND Source.lastModifiedDate <> target.lastModifiedDate
THEN
INSERT(idlastModifiedDate)
VALUES(source.id, source.lastModifiedDate)
OUTPUT $action, inserted.*, deleted.*;
The generated error is that we can not have an insert in the when matched case.
Can anyone has an idea how can we do this?
here is an example of scenarios:
scenario 1:
table 1 an table2 contain the following row:
Table1 (1,2011-10-05 14:55:00.403)
Table2 is empty
after execution, since the Table1.id is not present in Table2, we should insert this row into Table2
So Table2 should contain (1,2011-10-05 14:55:00.403)
Scenario 2:
Table1 (1,2011-10-05 14:55:00.403),(2,2011-10-05 14:55:00.403)
Table2 (1,2011-10-05 14:55:00.403)
after execution, because the first row already exist in Table2, we don't touch it, however the 2nd row don't exist yet so we have to insert it .
So Table2 should contain (1,2011-10-05 14:55:00.403),(2,2011-10-05 14:55:00.403)
Scenario 2:
Table1 (1,2011-10-05 14:55:00.403),(2,2011-10-05 00:00:00.403)
after execution, because the 2nd row has the same id but another lastModifiedDate, we have to delete from table2 the row having this id and then insert the 2nd row of table1
So after execution, Table2 should contain (1,2011-10-05 14:55:00.403),(2,2011-10-05 00:00:00.403)
Thanks in advance
No, you cannot have an INSERT in matched (https://msdn.microsoft.com/en-us/library/bb510625.aspx) But are you sure your disallowed INSERT shouldn't just be an UPDATE? Also seeing that you try to insert two columns into one column? (source.id, source.lastModifiedDate)==> idlastModifiedDate and the two matched conditions are the same?
So more like:
MERGE INTO Table2 AS target
USING (SELECT id, lastModifiedDate FROM Table1) AS source ON Source.id = target.id
WHEN NOT MATCHED BY TARGET
THEN INSERT(id,lastModifiedDate) VALUES(source.id,source.lastModifiedDate)
WHEN MATCHED THEN
UPDATE set lastModifiedDate = Source.lastModifiedDate
Related
I'm trying to insert a new row into a table which is an exact copy of another row except for the identifier. Previously I hadn't had the issue because there was an ID-column which didn't fill automatically. So I could just copy a row like this
INSERT INTO table1 SELECT * FROM table1 WHERE Id = 5
And then manually change the ID like this
WITH tbl AS (SELECT ROW_NUMBER() OVER (PARTITION BY Id ORDER BY Id) AS RNr, Id
FROM table1 WHERE Id = 5
UPDATE tbl SET Id = (SELECT MAX(Id) FROM table1) + 1
WHERE RNr = 2
Recently the column Id has changed to not be filled manually (which I also like better). But this leads to the error that I obviously can't fill that column while IDENTITY_INSERT is false. Unfortunately, I don't have the right to use SET IDENTITY_INSERT IdentityTable ON/OFF before and after the statement, which I also would like to avoid anyways.
I'm looking for a way to insert the whole row excluding the Id column without naming each other column in the INSERT and SELECT statement (which are quite a lot).
In the code below the maximum value of the ID gets added by one, so your integrity is not violated.
insert into table1
select a.Top_ID, Column2, Column3, ColumnX
from table1 t1
outer apply (select max(id_column) + 1as Top_ID from table1) as a
where t1.Id = 1
Okay, I found a way by using a temporary table
SELECT * INTO #TmpTbl
FROM table1 WHERE Id = 5;
ALTER TABLE #TmpTbl
DROP COLUMN Id;
INSERT INTO table1 SELECT * FROM #TmpTbl;
DROP TABLE #TmpTbl
Basically I have two tables. Table1 has millions of rows. Table2 has very few rows.
Table1 has field1 which is a product ID (not unique). Table2 has field2 which is just a list of productID's that need to be included from Table1 in the select statement.
SELECT Table1.*
FROM Table1
Join Table2 ON Table2.field2 = table1.field1
I found this code online and like its use for inserting data based on common column variables.
Select * from Table1
Merge into table1 as T using [table] as S
on T.[Last Name] = S.[Last Name] and T.[First Name] = S.[First Name]
When Matched then Update Set T.[DOB] = S.[DOB];
Problem is I want to get rid of the data that matched up from the source. So, once the information is has been matched and inserted into the target I want to delete the matched information from the source.
After the merge statement you can do a delete statement using inner join:
DELETE T1
FROM Table1 T1 INNER JOIN Table2 T2
ON T1.[Last Name] = T2.[Last Name] AND T1.[First Name] = T2.[Last Name];
Note: By default SQL table names are not case-sensitive, so both Table1 and table1 will refer to the same table. So please change the table
name.
Table1 contains Work Orders and Table2 contains Installers. I would like to insert a record into Table2 for Work Order 3906 in Table1 using unique identifier for that Work Order such that Table1GUID = Table2GUID . I'll worry about populating the new record later (all columns in Table2 can be blank for now except GUID which must be identical to corresponding GUID from Table1). Records for Table1 and Table2 are one to one.
This is NOT working: (0 row(s) affected)
INSERT INTO Table2 (Table2GUID)
SELECT Table1GUID FROM Table1
WHERE Table1.WOnumber = '3906'
This doesn't work either:
INSERT INTO Table2 (Table2GUID)
SELECT Table1GUID FROM Table1
INNER JOIN Table2 ON Table2GUID = Table1GUID
WHERE Table1.WOnumber = '3906'
I have 2 tables:
Table 1 and Table 2.
What i want to do, i want copy newly inserted records from Table1 to Table2 using trigger.
I created trigger on Table1, when bulk of data inserted in table1 it will copy newly inserted records in Table2. It work for single row insertion but not for multi row insertion.
Please let me know,what is wrong in that?
CREATE TRIGGER [dbo].[TRIG_TABLE1]
ON [dbo].[Table1]
AFTER INSERT AS
IF ##ROWCOUNT >=1
BEGIN
INSERT INTO Table2
(CustID
,DateCreated
,DateModify)
SELECT i.CustID
,i.DateCreated
,i.DateModify
FROM Table1 as i
WHERE (i.CustID IN (select CustID from INSERTED) and i.DateCreated IN (select DateCreated from INSERTED))
I don't get why aren't you using the INSERTED pseudo table directly:
CREATE TRIGGER [dbo].[TRIG_TABLE1]
ON [dbo].[Table1] AFTER INSERT AS
BEGIN
INSERT INTO Table2(CustID,DateCreated,DateModify)
SELECT CustID, DateCreated, DateModify
FROM INSERTED
END