Insert multiple records using stored procedure - sql

I have two tables
emplyoee (first table)
id primary key auto increment
emp_name varchar
student(second table)
id foriegnkey emplyoee.id
st_name varchar
I want to insert multiple student records for a single employeeid . My code is attached here , but this use to only one student record update. How can I write stored procedure for this need.
I am new with SQL server and stored procedure.
Could you please help me?
create procedure empst_Sp
#emp_name varchar(50),
#st_name varchar(50)
as
begin
insert into emplyoee (emp_name) values (#emp_name)
insert into student(id,st_name) values(SCOPE_IDENTITY(),#st_name)
end

For your case, you can try this code above ( I'm using XML parameter type)
CREATE PROCEDURE EmployeeIns
#EmployeeName NVARCHAR(50),
#Students XML
AS
/*
#Students : <Students>
<Student Name='Studen 1'/>
<Student Name='Studen 1'/>
</Students>
*/
BEGIN
DECLARE #StudenTable TABLE(Name NVARCHAR(50))
DECLARE #EmployeeId INT
INSERT INTO #StudenTable
SELECT Tbl.Col.value('#Name', 'NVARCHAR(50)')
FROM #Students.nodes('//Student') Tbl(Col)
INSERT INTO Emplyoee VALUES(#EmployeeName)
SET #EmployeeId = SCOPE_IDENTITY()
INSERT INTO Student
SELECT #EmployeeId, Name FROM #StudenTable
END
Update 1 :
Your table design should be look like this :
CREATE TABLE [dbo].[Emplyoee](
[Id] [int] IDENTITY(1,1) NOT NULL,
[Name] [nvarchar](150) NULL,
CONSTRAINT [PK_Emplyoee] PRIMARY KEY CLUSTERED
(
[Id] ASC
))
CREATE TABLE [dbo].[Student](
[EmployeeId] [int] NULL,
[Name] [nvarchar](150) NULL,
[Id] [int] IDENTITY(1,1) NOT NULL,
CONSTRAINT [PK_Student] PRIMARY KEY CLUSTERED
(
[Id] ASC
))
The execute code :
EXEC EmployeeIns #EmployeeName='trungtin1710', #Students = '<Students><Student Name="Studen 1"/><Student Name="Studen 1"/></Students>'

All you need is a local variable in which you can set the value retrieved from Scope_Identity:-
CREATE PROCEDURE empst_Sp
#emp_name varchar(50),
#st_name varchar(50)
AS
BEGIN
DECLARE #id INT
INSERT INTO emplyoee (emp_name) VALUES (#emp_name)
set #id = SCOPE_IDENTITY()
INSERT INTO student(id,st_name) VALUES (#id,#st_name)
END

As I understand:
If emplyoee with #emp_name is already exists then insert student records with ID of the emplyoee, if there is not any emplyoee with #emp_name then need to insert new emplyoee and student with ID of the new emplyoee. Yes?
CREATE PROCEDURE empst_Sp
#emp_name varchar(50),
#st_name varchar(50)
AS
BEGIN
DECLARE #EmplyoeeId int
SET #EmplyoeeId = NULL
select #EmplyoeeId = id
from emplyoee
where emp_name = #emp_name
IF #EmplyoeeId IS NULL
BEGIN
insert into emplyoee (emp_name) values (#emp_name)
SET #EmplyoeeId = SCOPE_IDENTITY()
END
insert into student(id, st_name) values(#EmplyoeeId, #st_name)
END

Related

SQLServer how to convert single row values in to multiple rows with each property as separat

I have a user defined type which is passed to my sql stored procedure:
CREATE TYPE [dbo].[LearningDelivery] AS TABLE(
[LearnAimRef] NVARCHAR(10) NOT NULL,
[AimType] INT NOT NULL,
[AimSeqNumber] INT NOT NULL,
);
i have a table with structure as below. I want to match join the type name from the above definition into the ElementName column of the FieldDefinitation table and insert separate insert statements. can anyone help me how to achieve this?
CREATE TABLE [dbo].[LearningAimData]
(
[Id] INT IDENTITY(1, 1) NOT NULL,
[LearnerId] INT NOT NULL,
[FieldId] INT NOT NULL,
[Data] VARCHAR(128) NOT NULL
)
I want to insert each type i.e LearnAimRef , AimType as individual row values in the LearningAimData.
I have a lookup table for [FieldId]
CREATE TABLE [dbo].[FieldDefinition]
(
[Id] INT IDENTITY(1, 1),
[FieldId] INT NOT NULL,
[Name] VARCHAR(50) NOT NULL,
[ElementName] VARCHAR(50) NOT NULL
)

Get Identity of destination table when using **DELETE FROM ... OUTPUT ... INTO**

I use bellow code to archive old data in ArchiveTable and delete archived data from SourceTable
DELETE FROM SourceTable
OUTPUT
DELETED.[ID],
DELETED.[Code],
DELETED.[Title]
INTO ArchiveTable([OldID], [Code], [Title])
WHERE Condition
Structure of tables:
CREATE TABLE [SourceTable](
[ID] [INT] IDENTITY(1,1) NOT NULL,
[Code] [VARCHAR](16) NULL,
[Title] [NVARCHAR](128) NULL,
CONSTRAINT [PK_SourceTable] PRIMARY KEY CLUSTERED ([ID] ASC)
)
GO
CREATE TABLE [ArchiveTable](
[ID] [INT] IDENTITY(1,1) NOT NULL,
[OldID] [INT] NOT NULL,
[Code] [VARCHAR](16) NULL,
[Title] [NVARCHAR](128) NULL,
CONSTRAINT [PK_ArchiveTable] PRIMARY KEY CLUSTERED ([ID] ASC)
)
GO
I need to return deleted records and ArchiveTable.[ID] to application. I change the code like this:
DELETE FROM SourceTable
OUTPUT
DELETED.[ID],
DELETED.[Code],
DELETED.[Title]
INTO ArchiveTable([OldID], [Code], [Title])
OUTPUT DELETED.*
WHERE Condition
This code return deleted records but I don't know how to get ID of ArchiveTable for this records. Look at ArchiveTable structure, It has OldID column that refer to SourceTable.ID and ID column that it is an Identity column of ArchiveTable. I need to ArchiveTable.ID in final result.
You can use a temporary table
CREATE TABLE #DeletedRows(
[ID] [INT] NOT NULL,
[Code] [VARCHAR](16) NULL,
[Title] [NVARCHAR](128) NULL
)
DELETE SourceTable
OUTPUT
DELETED.[ID],
DELETED.[Code],
DELETED.[Title]
INTO #DeletedRows([ID], [Code], [Title])
WHERE Condition
INSERT ArchiveTable([OldID], [Code], [Title])
OUTPUT INSERTED.*
SELECT [ID], [Code], [Title]
FROM #DeletedRows
DROP TABLE #DeletedRows
A variant with a table variable
DECLARE #DeletedRows TABLE(
[ID] [INT] NOT NULL,
[Code] [VARCHAR](16) NULL,
[Title] [NVARCHAR](128) NULL
)
DELETE SourceTable
OUTPUT
DELETED.[ID],
DELETED.[Code],
DELETED.[Title]
INTO #DeletedRows([ID], [Code], [Title])
WHERE Condition
INSERT ArchiveTable([OldID], [Code], [Title])
OUTPUT INSERTED.*
SELECT [ID], [Code], [Title]
FROM #DeletedRows
I found an interesting variant using DML with OUTPUT in SP and INSERT...EXEC... after that:
Test tables:
CREATE TABLE TestTable(
ID int NOT NULL PRIMARY KEY,
Title varchar(10) NOT NULL
)
CREATE TABLE TestTableLog(
LogID int NOT NULL IDENTITY,
OperType char(1) NOT NULL,
CHECK(OperType IN('I','U','D')),
ID int NOT NULL,
Title varchar(10) NOT NULL
)
DML procedures:
CREATE PROC InsTestTable
#ID int,
#Title varchar(10)
AS
INSERT TestTable(ID,Title)
OUTPUT inserted.ID,inserted.Title,'I' OperType
VALUES(#ID,#Title)
GO
CREATE PROC UpdTestTable
#ID int,
#Title varchar(10)
AS
UPDATE TestTable
SET
Title=#Title
OUTPUT inserted.ID,inserted.Title,'U' OperType
WHERE ID=#ID
GO
CREATE PROC DelTestTable
#ID int
AS
DELETE TestTable
OUTPUT deleted.ID,deleted.Title,'D' OperType
WHERE ID=#ID
GO
Tests:
-- insert test
INSERT TestTableLog(ID,Title,OperType)
EXEC InsTestTable 1,'A'
INSERT TestTableLog(ID,Title,OperType)
EXEC InsTestTable 2,'B'
INSERT TestTableLog(ID,Title,OperType)
EXEC InsTestTable 3,'C'
-- update test
INSERT TestTableLog(ID,Title,OperType)
EXEC UpdTestTable 2,'BBB'
-- delete test
INSERT TestTableLog(ID,Title,OperType)
EXEC DelTestTable 3
GO
-- show resutls
SELECT *
FROM TestTableLog
Maybe it'll be interesting to someone.

Stored Procedure With Input Output Scope Identity

I have two tables namely User and UserRole, where I want to pass the values via stored procedures with below tables. I need help how I can create a procedure which inserts into both the tables assuming a user has only one role i.e either User or Admin.
The Id parameter inserted into second table must be the Id of User Table.
Please suggest me.
CREATE TABLE [dbo].[User](
[Id] [int] IDENTITY(1,1) NOT NULL,
[Name] [nvarchar](50) NULL,
[Username] [nvarchar](50) NULL,
[Password] [nvarchar](50) NULL,
)
CREATE TABLE [dbo].[UserRole](
[Id] [int] IDENTITY(1,1) NOT NULL,
[UserId] [int] Foreign Key References User(ID)NOT NULL,
[Role] [nvarchar](50) NULL
)
CREATE PROCEDURE [dbo].[AddUserRole]
#Name VARCHAR(50),
#Username DATETIME,
#Password INT,
#Role NVARCHAR(50),
#Id INT OUT
AS
BEGIN
SET NOCOUNT ON;
INSERT INTO [WH].[dbo].[User]
(
Name,
Username,
Password
)
VALUES
(
# Name,
#Username,
#Password
);
SET # Id = SCOPE_IDENTITY();
INSERT INTO [WH].[dbo].[UserRole]
(
UserId,
Role
)
VALUES
(
#Id,
# Role
);
END;
Use output method, detail here
try Something like this
DECLARE #MyTableVar table( Id int);
INSERT INTO [WH].[dbo].[User] (Name, Username, Password)
OUTPUT INSERTED.Id INTO #MyTableVar
VALUES (#Name, #Username, #Password);
INSERT INTO [WH].[dbo].[UserRole] (UserId, Role )
SELECT Id, #Role FROM #MyTableVar;
Now this working fine !
CREATE TABLE [dbo].[TempUser](
[Id] [int] IDENTITY(1,1) NOT NULL Primary key,
[Name] [nvarchar](50) NULL,
[Username] [nvarchar](50) NULL,
[Password] [nvarchar](50) NULL,
)
CREATE TABLE [dbo].[TempUserRole](
[Id] [int] IDENTITY(1,1) NOT NULL,
[UserId] [int] Foreign Key References TempUser(ID)NOT NULL,
[Role] [nvarchar](50) NULL
)
--ALTER TABLE TempAddUserRole DROP CONSTRAINT FK__TempUserR__UserI__503293D2;
EXEC TempAddUserRole 'Gulshan','12 sep 2018','1','Admin'
EXEC TempAddUserRole 'Gulshan','12 sep 2018','1','Admin',
ALTER PROCEDURE [dbo].[TempAddUserRole]
#Name VARCHAR(50),
#Username DATETIME,
#Password INT,
#Role NVARCHAR(50)
AS
BEGIN
SET NOCOUNT ON;
declare #Id INT
INSERT INTO [TempUser]
(
Name,
Username,
Password
)
VALUES
(
#Name,
#Username,
#Password
);
SET #Id = SCOPE_IDENTITY();
INSERT INTO [TempUserRole]
(
UserId,
Role
)
VALUES
(
#Id,
#Role
);
END;

Insert Data Into three joined tables using a stored procedure

I have three tables [PublicationNotice], [PublicationNoticeClient] and [PublicationNoticeInvoice].
Table1 have one-to-one relation with table2 and table3.
I am using a stored procedure to insert data into the tables. My form consists of all attributes from table1, table2 and table3.
My problem is, when I Submit data into these three tables it inserts all data accept table2_id and table3_id in table1.
HINT: I am using ASP .Net and MSSQL
My stored procedure looks like this:
CREATE procedure [dbo].[AddUpdatePublicationNotice]
#ID bigint = NULL,
#Title varchar(max)= NULL,
#NewspaperName varchar(50) =NULL,
#Cities varchar(max)= NULL,
#PublicationSize varchar(8) =NULL,
#PublicationDate date =NULL,
#PublicationType varchar(50)= NULL,
#NewspaperPageNo smallint= NULL,
#Colored bit= NULL,
#CaseNature varchar(15)= NULL,
#ImagePath varchar(max)= NULL,
#ClientId bigint =NULL,
#InvoiceId bigint= NULL,
#CreatedById bigint = NULL,
#EditedById bigint= NULL,
#EditedDate datetime =NULL,
--******************************************--
#ClientName varchar(max)= NULL,
#ClientType varchar(50)= NULL,
#ClientContactPerson varchar(max)= NULL,
#ClientAddress varchar(max)= NULL,
#ClientCity varchar(50) =NULL,
#ClientCountry varchar(50)= NULL,
--******************************************--
#InvoiceDate date= NULL,
#InvoiceTotalAmount bigint= NULL,
#InvoicePaymentRecievedDate date= NULL,
#InvoiceChequeNo bigint= NULL,
#InvoiceBankName varchar(50)= NULL
--******************************************--
AS
Insert into PublicationNotice (
[Title]
,[NewspaperName]
,[Cities]
,[PublicationSize]
,[PublicationDate]
,[PublicationType]
,[NewspaperPageNo]
,[Colored]
,[CaseNature]
,[ImagePath]
,[ClientId]
,[InvoiceId]
,CreatedById
)Values(
#Title
,#NewspaperName
,#Cities
,#PublicationSize
,#PublicationDate
,#PublicationType
,#NewspaperPageNo
,#Colored
,#CaseNature
,#ImagePath
,#ClientId
,#InvoiceId
,#CreatedById)
insert into [dbo].[PublicationNoticeClient] (
[Name]
,[Type]
,[ContactPerson]
,[Address]
,[City]
,[Country]
,[CreatedById])
Values(#ClientName
,#ClientType
,#ClientContactPerson
,#ClientAddress
,#ClientCity
,#ClientCountry
,#CreatedById)
Insert Into [dbo].[PublicationNoticeInvoice] (
[Date]
,[TotalAmount]
,[PaymentRecievedDate]
,[ChequeNo]
,[BankName]
,[CreatedById])
Values (
#InvoiceDate
,#InvoiceTotalAmount
,#InvoicePaymentRecievedDate
,#InvoiceChequeNo
,#InvoiceBankName
,#CreatedById)
GO
I know I can first insert table2 and table3 values and then select the last inserted values from table2 and table3 (that are table2_id and table3_id) and then insert them into table1
Is there any other fast way to insert data like this ???
You can use ##IDENTITY , SCOPE_IDENTITY, IDENT_CURRENT or OUTPUT methods to retrieve last ID. The Output is the only secure one.
You need to insert into a table variable first and then query it
create table table1(
id int identity(1,1),
id_table2 int,
id_table3 int);
create table table2 (
id int identity(100,1),
val varchar(20));
create table table3 (
id int identity(200,1),
val varchar(20));
declare #varTable2 table (LastID int);
declare #varTable3 table (LastID int);
insert into table2
output inserted.id into #varTable2 values ('a');
insert into table3
output inserted.id into #varTable3 values ('a');
insert into table1 (id_table2, id_table3) values
( (select LastID from #varTable2),
(select LastID from #varTable3)
);
select * from table1
--You need to declare two variables to get identity values from table 2 and table 3 As
DECLARE #table2_identity AS INT
DECLARE #table3_identity AS INT
--After insert in Table 2 set table2_identity variable as follows
SET #table2_identity = SELECT SCOPE_IDENTITY()
--After insert in Table 3 set table3_identity variable as follows
SET #table3_identity = SELECT SCOPE_IDENTITY()
--Then assign those variable values in insert query of Table 1

Return NEWSEQUENTIALID() as an output parameter

Imagine a table that looks like this:
CREATE TABLE [dbo].[test](
[id] [uniqueidentifier] NULL,
[name] [varchar](50) NULL
)
GO
ALTER TABLE [dbo].[test] ADD CONSTRAINT [DF_test_id] DEFAULT (newsequentialid()) FOR [id]
GO
With an INSERT stored procedure that looks like this:
CREATE PROCEDURE [Insert_test]
#name as varchar(50),
#id as uniqueidentifier OUTPUT
AS
BEGIN
INSERT INTO test(
name
)
VALUES(
#name
)
END
What is the best way to get the GUID that was just inserted and return it as an output parameter?
Use the Output clause of the Insert statement.
CREATE PROCEDURE [Insert_test]
#name as varchar(50),
#id as uniqueidentifier OUTPUT
AS
BEGIN
declare #returnid table (id uniqueidentifier)
INSERT INTO test(
name
)
output inserted.id into #returnid
VALUES(
#name
)
select #id = r.id from #returnid r
END
GO
/* Test the Procedure */
declare #myid uniqueidentifier
exec insert_test 'dummy', #myid output
select #myid
Try
SELECT #ID = ID FROM Test WHERE Name = #Name
(if Name has a Unique constraint)