I have a utility script that is used to insert data into tables in my database. The script has a number of temp table in it that stores the new data to be inserted and a lot of it is related.
So, for example I have tables like so
DECLARE #Table1 TABLE
(
Table1ID INT
Table1Description VARCHAR(50)
Table1Code VARCHAR(5)
)
DECLARE #Table2 TABLE
(
Table2ID INT
Table2Description VARCHAR(50)
Table2Code VARCHAR(5)
)
DECLARE #Relationships TABLE
(
Table1Code VARCHAR(5)
Table2Code VARCHAR(5)
)
So the script populates the data in #Table1 and #Table2, but doesn't populate the ID fields. Once the data has been MERGEd into the database tables, I update the Table1ID and Table2ID fields in a separate statement as they are auto incrementing fields. Then when I use the #Relationships table to populate the database table, I can join to #Table1 and #Table2 to get the actual ID values.
I'm updating the script and I'm wondering if I can MERGE the data from #Table1/#Table2 into the database and update the ID fields in the temp table as part of the MERGE statement using the OUTPUT clause all in one statement?
I think the answer is no as I can't find anything mentioning updating an existing table with the OUTPUT clause, only inserting into a table.
I am still able to do what I need to do, so I'm not after alternatives. I just wondering if it is possible using the OUTPUT Clause
Thanks in advance
I'm debugging a data pipeline that consists of several tables and triggers.
We have a table called Dimension_Date defined as such:
CREATE TABLE [dbo].[Dimension_Date]
(
[id_date] [bigint] IDENTITY(1,1) NOT NULL,
[a_date] [datetime] NOT NULL,
[yoy_date] [date] NOT NULL
)
We also have three different tables in which other processes are inserting data (with transactions, although I don't have access to these processes). Each table contains a Datetime column (x_date) that needs to be inserted in the Dimension table only if that datetime doesn't exist already in the Dimension table. If it already exists, it shouldn't be inserted.
On each of these tables there is a trigger that, among other things, checks if the datetime exists in the Dimension table and if it isn't, inserts the new date. Once all the actions are performed, the content of TABLE_1, 2 and 3 are deleted. The triggers (of tables TABLE_1, 2 and 3) contain the following query:
CREATE TRIGGER [dbo].[insert_Date_Trigger]
ON [dbo].[TABLE_1]
AFTER INSERT
AS
BEGIN
INSERT INTO Dimension_Date (a_date, yoy_date)
SELECT DISTINCT x_date, DateADD(yy, -100, CONVERT(date, x_date))
FROM TABLE_1
WHERE NOT EXISTS (SELECT id_date FROM Dimension_Date
WHERE a_date = TABLE_1.a_date);
(...)
DELETE FROM TABLE_1
END
The problem is that these triggers are inserting duplicates in the Dimension table (two different id_date for the same a_date field), and I can't figure out where the problem is. Could it be that the processes might not be using transactions? Is there anything wrong with the query?
Any help would be greatly appreciated.
I have three tables that I need to get information from. One table has a code that I need to insert into another table. A third table ties these together.
Table one has a person ID number, a session number, a transaction date and a code. Some of the codes in this table are blank, so they need to be updated.
Table two has the same information as table one with an extra field of PaymentType.
Table three has the same data as table one with a PaymentType number, a date and a code to update to table one where the code is null.
The TransactionDate in table one need to match the Date or within date ranges in table three.
If the dates in table three are 2015-05-03, 2015-05-14 and 2015-05-30, how can I find a specific date within either of those ranges? If the date in table one is 2015-05-10, I need to find which date range it is in so that I can update table three with the proper code.
CREATE TABLE TableThree (
PersonNumber VARCHAR(8) NOT NULL
,SessionNumber VARCHAR(3) NOT NULL
,transaction_Dates DATE NOT NULL
,Code VARCHAR(3) NOT NULL
);
INSERT INTO
TableThree (PersonNumber, SessionNumber, transaction_Dates, Code)
VALUES
('ABC03854','590','2015-12-21','AAA')
,('ABC03862','591','2015-12-10','AAA')
,('ABC03862','591','2015-12-21','BBB')
,('ABC03893','595','2015-12-02','FFF')
,('ABC03893','595','2015-12-30','AAA')
,('ABC03970','597','2015-12-21','MMM')
,('ABC03976','598','2015-12-10','FFF')
,('ABC08931','519','2015-12-10','FFF')
,('ABC08931','519','2015-12-21','AAA')
,('ABC08931','519','2015-12-30','MMM');
CREATE TABLE mytable (
PersonNumber VARCHAR(8) NOT NULL
,SessionNumber INTEGER NOT NULL
,transaction_date VARCHAR(24) NOT NULL
,CODE VARCHAR(5) NOT NULL
);
INSERT INTO
mytable (PersonNumber,SessionNumber,transaction_date,CODE)
VALUES
('ABC03854',590,'2014-12-23 00:00:00.000',NULL)
,('ABC03862',591,'2014-12-16 00:00:00.000',NULL)
,('ABC03893',595,'2014-12-16 00:00:00.000',NULL)
,('ABC08931',519,'2015-12-22 00:00:00.000',NULL);
-- DUPLICATE OF Best way to get identity of inserted row? --
Well, I got an hard time finding a good title for this one.
I have two tables, with microsoft SQL server. Here's the structure:
TableA ( Id identity, Name varchar(20))
TableB ( Id identity, Name varchar(20))
Mapping ( IdTableA int, IdTableB int)
On TableA, I have an After Insert trigger. I want to "replicate" the insert into TableB, gets the new Ids and insert the mapping between the TableA's id and the TableB's id into the table Mapping.
I have no problem with inserting the data into TableB... but I have an hard time finding how to create a "map" between the two Ids...
Any help would be very appreciated.
I'm inserting a subset of a table into the same table and in order to create records in some mapping tables need to capture both the newly created identity PK, and the matching old PK..
If SQL would support it, something like:
Create table Test (pk identity, description varchar(10))
Declare #PKVALUES TABLE (NewPK int, OLdPk int)
INSERT INTO Test (description)
OUTPUT INSERTED.PK, Test.PK into #PKVALUES
Select description
From Test
Where ...
But, of course, SQL doesn't support Output of values from the FROM table during an INSERT operation..
The only set based alternative I've come across requires locking the whole table while creating the new PKs in a temporary table and then inserting them into the Test table using identity insert.
Is there some way I can accomplish this, (without having to resort to a one record at a time
approach or having to lock the whole table) ?
Thanks,
Ilmar
My preference would be to add a column to store the old pk in and then you can return it from the output clause. However, it is not always possible to change the table.
So, I have a sneaky trick but it involves doing twice as much work on your db. What you do is put the Old PK in the description field in the intial insert. Then you update the description to the value of teh old PK by joining on the description field to the PK.
Create table Test (pk identity, description varchar(10))
Declare #PKVALUES TABLE (NewPK int, OLdPk varchar(10)
INSERT INTO Test (description)
OUTPUT INSERTED.PK, INSERTED.Description into #PKVALUES
SELECT PK from Test where....
UPDATE tnew
SET description = told.description
FROM test told
JOIN test tnew ON CAST(told.PK AS varchar (10)) = t.description