How to get the primary key values after insert select statement - sql-server-2008

I need to create a SQL script with many step in it.
First of all, I need to insert data into a Parent Table.
How can I Get the list of primary key value
Here is an example of what I'm trying to perform.
MyParentTable
MyParentID PK
col1,
col2,
col3
--INSERT VALUE INTO THE PARENT TABLE
insert into MyParentTable(col1,col2,col3)
select SDATA1,SDATA2,SDATA3
from ExampleTables
I Would like to get the list of my newly entries.
How to do that?
IMPORTANT NOTE : Consider that MyParentTable can alreaydy contains data.

insert into dbo.MyParentTable(col1,col2,col3)
output inserted.identity_column_name
select SDATA1,SDATA2,SDATA3
from dbo.ExampleTables;
If there are foreign keys involved, you may have to use a #table variable for temporary holding.
DECLARE #t TABLE(id INT);
insert into dbo.MyParentTable(col1,col2,col3)
output inserted.identity_column_name INTO #t
select SDATA1,SDATA2,SDATA3
from dbo.ExampleTables;
SELECT id FROM #t;

Related

MySQL - How to insert or update from source table to target table with different Keys?

I have 2 tables with different structures.
CREATE TABLE test1
(
id INTEGER PRIMARY KEY,
EmpName VARCHAR(50),
Empid INTEGER
);
CREATE TABLE test2
(
Empid INTEGER PRIMARY KEY,
EmpFName VARCHAR(50),
EmpLName VARCHAR(50)
);
Is there a way to insert rows from test2 table into test1? If the row exists in test1 it should update the row as well. I think it's possible with Merge statement but it's not available for MySQL. Is there a similar function like this in MySQL?
I've looked into INSERT ... ON DUPLICATE KEY UPDATE but the tables should have the same primary keys.
I think this can help you.
Create Trigger to detect when insert/update data in your table test2.
Inside Trigger use REPLACE INTO to change data in your table test1.
Please check this link for additional of REPLACE INTO command.
Is there a way to insert rows from test2 table into test1? If the row exists in test1 it should update the row as well
UPDATE test1
JOIN test2 USING (Empid)
SET test1.EmpName = CONCAT_WS(' ', EmpFName, EmpLName)
Pay attention - EmpName max length is 50 whereas total length of combined name may be up to 50+1+50=101, so the combined value may be truncated. Increase max length for EmpName.
If you need to perform this operation automatically when the data in test2 is inserted/updated then use AFTER INSERT and AFTER UPDATE triggers, like
CREATE TRIGGER tr
AFTER INSERT -- and the same trigger on AFTER UPDATE event
ON test2
FOR EACH ROW
UPDATE test1
SET EmpName = CONCAT_WS(' ', NEW.EmpFName, NEW.EmpLName)
WHERE test1.Empid = NEW.Empid;

Mysql Insert if not exist in two column

I looked into MySQL duplicate key but cant figure it out.
I have a table like below:
id series chapter path(can be unique)
I want only insert data and not update. Lets say I have data like below:
seri:Naruto, klasor:567 ==> If both of these exist in table then do not insert.
seri:Naruto, klasor:568 ==> If Naruto exist but 568 does not exist then do insert.
How can I achieve this?
Easiest way would be to define unique index with two columns on that table:
ALTER TABLE yourtable ADD UNIQUE INDEX (seri,klasor);
You may also define two column primary key, which would work just as well.
Then use INSERT IGNORE to only add rows when they will not be duplicates:
INSERT IGNORE INTO yourtable (seri, klasor) VALUES ('Naruto',567);
INSERT IGNORE INTO yourtable (seri, klasor) VALUES ('Naruto',568);
Edit: As per comments, you can't use UNIQUE INDEX which complicates things.
SET #seri='Naruto';
SET #klasor=567;
INSERT INTO yourtable
SELECT seri,klasor FROM (SELECT #seri AS seri, #klasor AS klasor)
WHERE NOT EXISTS (SELECT seri, klasor FROM yourtable WHERE seri=#seri AND klasor=#klasor);
You may use the above query with two local variables or convert it to single statement by replacing the local variables with actual values.
Better way would be to use stored procedure:
CREATE PROCEDURE yourinsert (vseri VARCHAR(8), vklasor INT)
BEGIN
DECLARE i INT;
SELECT COUNT(*) INTO i FROM yourtable WHERE seri=vseri AND klasor=vklasor;
IF i=0 THEN
INSERT INTO yourtable (seri,klasor) VALUES (vseri, vklasor);
END IF;
END;
This would allow you to perform the INSERT using:
CALL yourinsert('Naruto',567);
INSERT INTO table_name (seri, klasor) VALUES ('Naruto',567)
WHERE NOT EXISTS( SELECT seri,klasor FROM table_name WEHERE seri='Naruto' AND klasor=567
)
Hope this helps..

Getting multiple records that are inserted in a table

Hi all I would like to get all the Id's that are newly inserted. Actually I am inserting the data in to a table based on foreign key id.
Insert into table()
Values(SELECT * FROM table where fId=X)
Here the two tables are same, so after inserting the data I would like to return all the Identities that got inserterd
You need to use OUTPUT (https://msdn.microsoft.com/en-us/library/ms177564.aspx) clause in your insert. Here's a working example:
DECLARE #tmp TABLE (id INT IDENTITY(1,1), txt VARCHAR(100))
INSERT INTO #tmp (txt)
OUTPUT INSERTED.id
VALUES ('a'),('b')
So for your query - which is not a valid insert statement - it would be:
Insert into table()
OUTPUT INSERTED.id_column_you_need_to_be_returned
Values(SELECT * FROM table where fId=X)

SQL Insert from table to table prevented by duplicate primary key from source table

I am trying to populate a products table on MySQL with latest products, which are retrieved and stored in products_temp table.
So the method for this is straight forward, simply doing an INSERT to products from products_temp, as such:
INSERT INTO products ( select products_temp.* FROM products_temp )
Problem is, it results in a duplicate primary key error, because of the id from products_temp clashing with the id in products.
Can someone tell me how to fix this please?
I tried declaring the fields in the select statement without the id, but that results in "Column count doesn't match value count at row 1"
Any help would be appreciated.
Thanks!
You'll need to declare the columns except the ID on both the INSERT and the SELECT, since the number of fields need to match, and id (as you noticed) can't be inserted as is into the destination table.
INSERT INTO DestTable (field1, field2, field3)
SELECT field1, field2, field3 FROM SourceTable;
An SQLfiddle to test with.
EDIT: You could do it in a bit more hacky way to simplify the insert. You can create a trigger that simply forces the primary key to NULL on insert.
CREATE TRIGGER t_DT BEFORE INSERT ON DestTable
FOR EACH ROW
SET NEW.id = NULL;
then a copy from table to table can be done as simply;
INSERT INTO DestTable SELECT * FROM SourceTable;
Another SQLfiddle.
How about something like:
INSERT INTO products
(
select products_temp.* FROM products_temp
where key not in (select key from products)
)

Output current id of inserted record using OUTPUT in a trigger

I need to do this: On inserted record I need to store Inserted item identity and selected item identity. (Example below)
I'm using after insert trigger (basically I copy one row from one table into another and do some more modifications.
I have a table parameter like this:
DECLARE #Tempequipment TABLE
(Equipment_Id int,
DefaultEquipment_Id INT)
Then I insert into table like this:
INSERT INTO dbo.tblEquipmentType
( Name, EquipmentType_Id)
SELECT name,(SELECT Equiment_Id FROM INSERTED)
FROM dbo.tblDefaultEquipmentType
This works fine!
What I need to do is: I need to insert into #TempEquipment EquipmentTypeId's that were just ineserted (can be more than one) and DefaultEquipmentTypeId's that were just copied.
I was thinking about doing something like:
INSERT INTO dbo.tblEquipmentType
( Name, EquipmentType_Id)
Output EquipmentTypeId, DefaultEquipmentTypeId into #TempEquipment
SELECT name,(SELECT Equipment_Id FROM INSERTED)
FROM dbo.tblDefaultEquipmentType
but of course this is not going to work, since it cannot get values from select statement, and not written correctly.
Any help is appreciated!
UPDATE:
I have an Item. Item can be built on different equipment. Equipment has types (foreign key. And equipmentType has attributes (foreignkey).
So this mean that we have four tables Item->Equipment->EquipmentType->EquipmentAttribute.
I need to store default EquipmentTypes and default EquipmentAtrributes for that type.
So I also got these replationship: Equipment->DefaultEquipmentType->DefaultEquipmentAttribute.
Now, When I insert new Item and select an equipment I want to copy defaults over to real tables (EquipmentType, EquipmentAttribute).
Is it clear at least a little?
Aside from how you're trying to do this (which isn't working), what specifically are you trying to do?
It may be that this can be resolved by changing / normalizing your paradigm, instead of some kind of exotic code. For example, it looks odd to have a customers table with an orderID field in it. Unless your customers only ever order one thing... I would have expected to see a customers table, an items table, and then an orders table that joined customers with items.
Hope that makes sense -- but anyway, if not, can you post your table structure, and maybe be a little more clear on what you know ahead of time (e.g., I imagine you know who your customers are, and what they ordered...before you do the insert...yes?)
For an INSERT statement you can only access the columns which are in the insert column list, so the solution is to rewrite the statement as a MERGE statement which can access all the columns including columns which are in the INSERT target table for instance IDENTITY columns.
In the demo I've used dbo.INSERTED to emulate the virtual table INSERTED from the trigger.
USE master
GO
IF DB_ID('MergeOutputExample') IS NOT NULL
DROP DATABASE MergeOutputExample
GO
CREATE DATABASE MergeOutputExample
GO
USE MergeOutputExample
GO
DECLARE #Tempequipment TABLE
(EquipmentId int,
DefaultEquipmentId INT,
ID int);
CREATE TABLE dbo.INSERTED
(
EquipmentTypeId int PRIMARY KEY
);
CREATE TABLE dbo.tblEquipmentType
(
ID int IDENTITY(1,1),
Name varchar(50),
EquipmentTypeId int PRIMARY KEY
);
CREATE TABLE dbo.tblDefaultEquipmentType
(
EquipmentTypeId int,
DefaultEquipmentTypeId int IDENTITY(1,1) PRIMARY KEY,
Name varchar(50)
);
INSERT dbo.inserted
(
EquipmentTypeId
)
VALUES (1);
INSERT dbo.tblDefaultEquipmentType
(
EquipmentTypeId,
Name
)
VALUES (
1,
'Hammer'
);
MERGE dbo.tblEquipmentType AS ET
USING (
SELECT DE.EquipmentTypeId,
DE.DefaultEquipmentTypeId,
DE.Name
FROM dbo.tblDefaultEquipmentType DE
INNER JOIN dbo.INSERTED I
ON DE.EquipmentTypeId = I.EquipmentTypeId
) AS DET
ON ET.EquipmentTypeId = DET.EquipmentTypeId
WHEN NOT MATCHED BY TARGET
THEN INSERT
(
Name,
EquipmentTypeID
)
VALUES
(
DET.Name,
DET.EquipmentTypeID
)
OUTPUT DET.EquipmentTypeId,
DET.DefaultEquipmentTypeId,
INSERTED.ID
INTO #Tempequipment;
SELECT *
FROM #Tempequipment;
SELECT *
FROM dbo.tblEquipmentType;