Get the mapping for the inserted Id and the existing Id in SQL Server while cloning - sql

I want to clone the data in a table using existing data with the insert and select statement like:
INSERT INTO Foundation.Products
OUTPUT Inserted.Id INTO #insertedIdTable -- Need to get the existing Id also
SELECT Name, SupplierId, CategoryId
FROM Foundation.Products
WHERE Id = #existingProductId
Is there any way to map the inserted and the existing Id in the table. For which existing Id which new Id is created?
I know we can do this using the MERGE statement with Source and Destination as the same table
MERGE Foundation.Products
USING (SELECT * FROM Foundation.Products WHERE Id = #existingProductId) AS [Source]
ON (1=0) -- always insert
WHEN NOT MATCHED THEN
INSERT (Name, SupplierId, CategoryId)
VALUES ([Source].Name, [Source].SupplierId,[Source].CategoryId)
OUTPUT INSERTED.Id, [Source].Id;

No, what you want can't be done with insert - output. You'll have to use merge. Is there some reason why you don't want to use merge?

Related

Foreach insert statement based on where clause

I have a scenario where I have thousands of Ids (1-1000), I need to insert each of these Ids once into a table with another record.
For example, UserCars - has columns CarId and UserId
I want to INSERT each user in my Id WHERE clause against CarId 1.
INSERT INTO [dbo].[UserCars]
([CarId]
,[UserId])
VALUES
(
1,
**My list of Ids**
)
I'm just not sure of the syntax for running this kind of insert or if it is at all possible.
As you write in the comments that my list of Ids is coming from another table, you can simply use select into with a select clause
See this for more information
insert into UserCars (CarID, UserID)
select CarID, UserID
from othertable
In the select part you can use joins and whatever you need, complex queries are allowed as long as the columns in the result match the columns (CarID, UserID)
or even this to keep up with your example
insert into UserCars (CarID, UserID)
select 1, UserID
from dbo.User
if your data exists on a file, you can use BULK INSERT command, for example:
BULK INSERT UserCars
FROM '\\path\to\your\folder\users-cars.csv';
Just make sure to have the same columns structure both in the file and in the table (e.g. CarId,UserId).
Otherwise, follow #GuidoG comment to insert your data from another table:
insert into UserCars (CarID, UserID) select CarID, UserID from othertable

Create a record in table A and assign its id to table B

I have a set of companies and for each of them, I need to generate a UUID in another table.
companies table
detail_id (currently NULL for all companies)
details table
id
uuid
date
...
I'd like to update all companies with newly created detail like this:
UPDATE companies
SET details_id =
(
INSERT INTO details
(uuid, date)
VALUES (uuid_generate_v1(), now()::date)
RETURNING id
)
But that gives me a syntax error since I can't use INSERT INTO inside UPDATE.
What is a proper way to create a row in the details table and immediately set the newly created id in the companies table?
(I am using Postgres)
You can use a data-modifying CTE:
with new_rows as (
INSERT INTO details ("uuid", "date")
VALUES (uuid_generate_v1(), current_date)
RETURNING id
)
update companies
set details_id = new_rows.id
from new_rows

Using output to capture auto increment identity, plus past identity mapping table

I am trying to make exact copies of data in SQL, with new clientIDs, but keep the existing data in the old client as well. I will be inserting the data into a table with an auto incrementing integer primary key ID. I need to retain the ID's of the Old records and the new records together so I can continue using this mapping as I copy the different table data so I can maintain relationships.
At this point I have the following:
INSERT INTO [dbo].[Driver]
OUTPUT inserted.ID
inserted.Name
inserted.ClientID
SELECT Name,
1234 AS clientID
FROM dbo.Driver
I am wondering if there is a way to also select the old ID of the driver in the Output so I can then insert all of this into a holding table using the OUTPUT. So I need to end up with the following after I perform the insert into the dbo.Driver table so I can also insert these values into a temp table:
NewID
OldID
Name
ClientID
At this point I don't know of a way to pull the Original ID from the original record.
I ended up using MERGE INTO to keep track of the old ID as per the following SO post:
How to use OUTPUT to capture new and old ID?
you can try...
INSERT INTO dbo.Driver (oldID, Name, clientID)
SELECT
B.ID,
A.Name,
1234 AS clientID
FROM dbo.Driver A
LEFT JOIN dbo.Driver B ON A.Name = B.Name AND A.clientID = b.clientID
or maybe just
INSERT INTO dbo.Driver (oldID, Name, clientID)
SELECT
ID,
Name,
1234 AS clientID
FROM dbo.Drive

merge statement when not matched by source then insert to another table

I have created two tables customersrc and customertemp with the columns:
customertemp
ID name age addr cityid isactive
34 Gi 24 Chennai 1 1
customersrc
CustomerId CustomerName CustomerAge CustomerAddress
1 Gi 24 madurai
2 Pa 23 Tirupur
3 MI 27 Tirupur
Now I need to insert pa and mi data value to the temp table bcz it is not matched with the rows of customertemp. And the row gi data will be updated which was matched.
I used the following MERGE statement
DECLARE #cityid INT SET #cityid=1
MERGE Temp.dbo.customersrc as src_customer
USING ( SELECT CustomerName,CustomerAge,CustomerAddress FROM customertemp) as temp_customer
ON src_customer.name=temp_customer.CustomerName
AND
src_customer.cityid=#cityid
WHEN MATCHED THEN
UPDATE SET
src_customer.age=temp_customer.CustomerAge,
src_customer.addr=temp_customer.CustomerAddress,
src_customer.isactive=1
WHEN NOT MATCHED BY SOURCE THEN
UPDATE SET src_customer.isactive=0 ; -- here i need the insert statement to insert in another table
Questions:
is it possible to write insert statement inside the when not matched by source query?
if it is not possible then how to achieve this using merge?
in a simple set theory I need to put the customersrc(table_B)-customertemp (table_A). B-A value into the another or temp table.
One of the main usages of the MERGE statement is to perform so called "UPSERTS" (Update matching records, insert new records), so it is definitely possible to do what you want. Just add the following to the last part of your MERGE statement:
WHEN NOT MATCHED BY TARGET THEN
INSERT (name, age, addr, cityid, isactive)
VALUES (CustomerName, CustomerAge, CustomerAddress, #cityid, 1)
If you also need to insert data into a 3rd table, depending on whether rows are updated or inserted, you can use the OUTPUT clause of the merge statement. Check out the documentation: http://technet.microsoft.com/en-us/library/ms177564.aspx
Me: Why do you want to insert to another table?
You: To show the user who are not in the customertemp table.
So your requirement is not to insert into another table. Your requirement is to get the missing users.
You could do that with a dummy UPDATE (SET SomeCol = SomeCol) and OUTPUT. But that is a hack that I would try to avoid.
It is probably easier to do this in two statements. Here's how you'd get the missing rows:
SELECT temp_customer.*
FROM (SELECT CustomerName,CustomerAge,CustomerAddress FROM customertemp) as temp_customer
LEFT JOIN customersrc ON src_customer.name=temp_customer.CustomerName AND src_customer.cityid=#cityid
WHERE customersrc.cityid IS NULL

Inserting the data at a time in 3 tables using an array into Postgresql database

I have to insert the data at a time in 3 tables into PostgreSQL database.
I have to insert data into first and Second table is directly.
But The third table which i received data as array and inserted into 3rd table as same.
Is data inserting as array into PostgreSQL available or possible?
If it possible how can I insert can some correct me
How can i do the same mechanism with Wso2 DSS 3.0.1.
My query is
with first_insert as (insert into sample(name,age)
values(?,?)
RETURNING id
),
second_insert as (insert into sample1(empid,desig)
values((select id from first_insert),?)
RETURNING userid
)
insert into sample2(offid,details)
values((select userid from second_insert),?)
Not sure I understood your question exactly, but at least you could use insert into ... select:
with cte_first_insert as
(
insert into sample1(name, age)
values('John', 25)
returning id
), cte_second_insert as (
insert into sample2(empid, desig)
select id, 1 from cte_first_insert
returning userid
)
insert into sample3(offid, details)
select userid, 'test'
from cte_second_insert;
sql fiddle demo