SQL 2 Inserts based on return of first - sql

I am generating a series of Inserts based on data from an Excel file into SQL Server 2014
How do I get the value of the ID of the first INSERT to put into the second
Simplified example where Ontario is a Province of Canada:
Insert into country (Name) values('canada');
Insert into provinces (CountryId, Name) values (???,'ontario');
There are 100 inserts so performance is not an issue.

declare #countryid int
Insert into country (Name) values('canada');
SELECT #countryid = SCOPE_IDENTITY()
Insert into provinces (CountryId, Name) values (#countryid,'ontario');

the answer above from tshoemake shows how you can insert one record and get the result. If you want to insert many records in Country and then many records in provinces, you might want to have a look at the OUTPUT clause. You'll have to work out how to join in your list of provinces because this code will just add Ontario to every country:
create table __country
(
id int identity(1,1) primary key,
Name varchar(5000)
)
CREATE TABLE __Provinces (
countryid int,
name varchar(5000)
)
CREATE TABLE #tempIDs
(
id int
)
INSERT INTO __Country
OUTPUT inserted.id
INTO #tempIDs
values ('canada'), values('USA')
insert into __Provinces
select #tempIDs.id, 'ontario'
from #tempIDs
join __country
ON __country.id = #tempIDs.id
select * from __Provinces

Related

SQL Inserted table trigger

If I run the following select statement inside an insert trigger, is it possible that it will return more than one result?:
DECLARE #variable char(1) = (SELECT ID FROM inserted)
If so, then what's the best to handle it?
Here is the problem that I am trying to solve: Every time when the new record is inserted into a table, I want to take the newly inserted ID and insert it into another table(if it doesn't exists).
Thank you!
Instead of
DECLARE #variable char(1) = (SELECT ID FROM inserted)
You can do something like following:
Declare #VarTempTbl as table (id int)
Insert into #VarTempTbl (id)
Select id from inserted
So that you can get those values for further processing
Now, I had created Two tables One for Master table and another for When any Insertion happens in that Master table, that entry has to inserted into the another table.
CREATE TABLE tblEmployee
(
Id int Primary Key,
Name nvarchar(30),
Gender nvarchar(10),
DepartmentId int
)
CREATE TABLE tblEmployee_New
(
Id int Primary Key,
Name nvarchar(30),
Gender nvarchar(10),
DepartmentId int
)
Trigger:
CREATE TRIGGER TR_EMPLOYEEDETAILS_AFTEROFINSERT
ON TBLEMPLOYEE
AFTER INSERT
AS
BEGIN
TRUNCATE TABLE tblEmployee_New
INSERT INTO TBLEMPLOYEE_NEW(ID, NAME, GENDER, DEPARTMENTID)
SELECT ID, NAME, GENDER, DEPARTMENTID
FROM INSERTED
END
Now Lets try to insert into record into a master table
Insert into tblEmployee values (1,'John', 'Male', 3)
Insert into tblEmployee values (2,'Mike', 'Male', 2)
It has automatically insert the newly inserted records into the another table.
If your want to remove the Previous records then add a drop Statement in that above Trigger.
Note: You can also use #Temp Table instead of creating a another table('tblEmployee_New')
Kinldy Share your comments

How can insert value by selecting from another

I have three tables. table1 for insert data and table2, table3 for selecting data.
table1:
int id,
varchar name,
varchar gender,
varchar category,
table2:
int id,
varchar gender,
table3:
int id,
varchar category,
According to these tables, i'm using stored procedure as below:
Create procedure ABC
(
#id varchar(10),
#name varchar(11),
#gender varchar(10),
#category varchar(10)
)
As
begin
Insert into table1(id, name, gender, category) select #id, #name, g.id, c.id from gender g, category c where g.gender=#gender and c.category=#category
end
Now, using this if gender or category is empty then data is not inserting. Please tell me where i'm wrong and tell best query to insert data using select query. Please help me to solve the problem. Thanks
You are using and in where clause which means only if gender = #gender then it is selecting any record.
Create procedure ABC
(
#id int, ----- change this to int since id is int type in your table
#name varchar(11),
#gender varchar(10)='',
#category varchar(10)=''
)
As
begin
Insert into table1(id, name, gender, category)
select #id, #name, g.id, c.id from gender g, category c
where (g.gender=#gender or isnull(#gender,'')='') and (c.category=#category or isnull(#category,'')='')
end
Although you may use this approach. But since you want to insert id of gender and category column in your table, then on passing null or blank value what is your expected id to be put in your record.
It is better if you first check gender and category value in your respected table and if record not found then insert it in your table and then save its corresponding id in your final table.

Data Definition Language (DDL) Query SQL

I'm new in query and SQL server, and I wanted to know about DDL.
I have an attribute in my Table which has more than 1 value, such as
Size = {'S', 'M', 'L'}.
How could i make the attribute in my Table with query, so i can insert multi values to one of my attribute?
You don't want to do this, because this is denormalizing your data. But, if you must.
declare #table table (id int identity(1,1), size varchar(16))
insert into #table
values
('S')
,('M')
select * from #table
update #table
set size = size + ',M'
where id = 1
select * from #table
Here is a one to many approach with a foreign key
create table #items (id int identity(1,1), descrip varchar(64))
insert into #items
values
('shirt'),
('pants')
create table #item_sizes (id int identity(1,1), size char(1), item_id int)
alter table #item_sizes
add constraint FK_item foreign key (item_id) references #items(id)
insert into #item_sizes
values
('S',1)
,('M',1)
,('L',1)
,('S',2)
select
ItemID = i.id
,i.descrip
,isiz.size
from #items i
inner join #item_sizes isiz
on isiz.item_id = i.id
drop table #items, #item_sizes
As per your requirement :
Product (...,ProductSize);
INSERT INTO Product (ProductSize) VALUES ('S')
How to query the row of ProductSize so i can insert more than one values in SQL? –
you can query like below
select * from Product where ProductSize like '%S%' or ProductSize like '%L%' or ProductSize like '%M%'

Insert a row if it doesn't exist via query

I am trying to write a query that will insert a group of people into a table if that person does not exist. For example, I have table full of people and I need to add more people into the database and I don't know if they are already there. I do know that the social security number (ssn) will never be the same for two people. Could a query be used to check if the ssn is in the table and if not insert the person into the table? If the ssn is in the table then go to the next person and check?
I was thinking about using a stored procedure, but I do not have any rights to create a store procedure.
You can insert your data into a table variable or temp table and then INSERT INTO table from temp table where it does not exists in your table.
DECLARE #Inserted AS TABLE
(
NAME VARCHAR(50)
,SSN DECIMAL(10, 0)
)
INSERT INTO #Inserted
( NAME, SSN )
VALUES ( 'Bob', 123456789 )
, ( 'John', 123546789 )
, ( 'James', 123456798 )
INSERT INTO MyTable
SELECT *
FROM #Inserted AS i
LEFT OUTER JOIN MyTable AS m
ON i.SSN = m.SSN
WHERE m.SSN IS NULL
Here are a couple ideas to get you started. I use MERGE a lot because it offers so much control. You could also look into the IN clause as part of a WHERE predicate in the INSERT SELECT statement.
MERGE
DECLARE #PERSONTABLE TABLE (ID INT PRIMARY KEY IDENTITY(1,1), FirstName VARCHAR(max))
INSERT INTO #PERSONTABLE (FirstName) VALUES ('Bill'),('Sally'),('Bob')
DECLARE #NEWPEOPLE TABLE (FirstName VARCHAR(max))
INSERT INTO #NEWPEOPLE (FirstName) VALUES ('Jim'), ('Sally')
--MERGE
MERGE INTO #PERSONTABLE AS T
USING #NEWPEOPLE AS S
ON (T.FirstName = S.FirstName)
WHEN NOT MATCHED BY TARGET THEN
INSERT (FirstName) VALUES (S.FirstName);
SELECT * FROM #PERSONTABLE
EXCEPT
DECLARE #PERSONTABLE TABLE (ID INT PRIMARY KEY IDENTITY(1,1), FirstName VARCHAR(max))
INSERT INTO #PERSONTABLE (FirstName) VALUES ('Bill'),('Sally'),('Bob')
DECLARE #NEWPEOPLE TABLE (FirstName VARCHAR(max))
INSERT INTO #NEWPEOPLE (FirstName) VALUES ('Jim'), ('Sally')
--EXCEPT
INSERT INTO #PERSONTABLE (FirstName)
SELECT FirstName FROM #NEWPEOPLE
EXCEPT
SELECT FirstName FROM #PERSONTABLE
SELECT * FROM #PERSONTABLE
You could do it like this if the new people are in another table. If not, then use Vladimir's solution.
INSERT INTO People(ssn, firstname, lastname)
SELECT ssn, firstname, lastname
FROM newpeople
WHERE ssn not in (select ssn from people )
INSERT INTO People(ssn, firstname, lastname)
SELECT np.ssn, np.firstname, np.lastname
FROM newpeople np
LEFT JOIN People p on np.ssn = p.ssn
WHERE p.ssn IS NULL
Here's another option I use a lot. Normally joins are better than sub-selects... if the joined table value is null you know you don't have a hit in the joined table.

how to get id of newly inserted rows using openxml?

I have a XML block which I want to insert into database. database contains 3 tables namely itemMapping, links and category. Links table will have only link from XML, category table will have category from XML.
<item>
<link>http://google.com</link>
<category>search engine</category>
<category>android</category>
<category>gmail</category>
</item>
Here come my confusion, 'itemMaping' table contains following columns :
ID, LinkID, CategoryID
In itemMapping table I have to insert linkID and categoryID of newly inserted rows. So according to sample XML itemMapping table will have 3 records for each category, but to insert record in this table i will need linkID and categoryID from above. How I can achieve this? I want to do this in single SP if possible.
Hi Consider the following tables:
Country Table
CountryID CountryName LastEditUser
Province table
ProvinceID ProvinceName CountryID LastEditUser
Consider CountryID and ProvinceID were identity columns.
IN SQL YOU can insert records to these two tables using a single stored procedure take a look at the quick example
CREATE PROCEDURE InsertProvince
(
#ProvinceName VARCHAR(128),
#CountryName VARCHAR(128),
#LastEditUser VARCHAR(128)
)
AS
DECLARE #CountryID INT
INSERT INTO Country
(CountryName, LastEditUser)
VALUES
(#CountryName, #LastEditUser)
#CountryID = SCOPE_IDENTITY();
INSERT INTO Province
(ProvinceName, CountryID, LastEditUser)
VALUES
(#ProvinceName, #CountryID, #LastEditUser)
END
SQL Server has a function called scope_identity, it returns the last identity value inserted into an identity column in the same scope. A scope is a module: a stored procedure, trigger, function, or batch. Therefore, two statements are in the same scope if they are in the same stored procedure, function, or batch.
Insert into Links and capture the LinkID with scope_identity() to a variable. Insert into Category and capture the generated ID's in a table variable. Use that table variable as source for the insert to ItemMapping.
Assuming your tables look like this.
create table Category
(
CategoryID int identity primary key,
Name varchar(50)
)
create table Links
(
LinkID int primary key identity,
Link varchar(50)
)
create table ItemMapping
(
LinkID int references Links(LinkID),
CategoryID int references Category(CategoryID),
primary key(LinkID, CategoryID)
)
You can do like this using an XML variable #XML.
declare #IDs table(ID int)
declare #LinkID int
insert into Links(Link)
select T.X.value('.', 'nvarchar(50)')
from #XML.nodes('item/link') as T(X)
set #LinkID = scope_identity()
insert into Category(Name)
output inserted.CategoryID into #IDs
select T.X.value('.', 'nvarchar(50)')
from #XML.nodes('item/category') as T(X)
insert into ItemMapping(LinkID, CategoryID)
select #LinkID, I.ID
from #IDs as I
SE-Data