Insert Data Into three joined tables using a stored procedure - sql

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

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
)

Insert data into teable variable

I am trying to insert data through my stored procedure and finding difficulty in doing it.
I tried doing below code but it doesn't work.
DECLARE #AddressRecordsToPurge TABLE
(
RowID INT NOT NULL PRIMARY KEY IDENTITY(1,1),
GUIDValue Nvarchar(max) NOT NULL,
GuidColumn Nvarchar(max) NOT NULL,
GuidTable Nvarchar(max) NOT NULL
)
Insert Into #AddressRecordsToPurge values ( Select AccountGUID FROM APPLICATIONCONTRACT WHERE ApplicationNumber =#ApplicationNumber AND AccountGUID IS NOT NULL, 'AccountGUID', 'PREVIOUSLENDERSREF');
my first value is query and last 2 values are strings. Please help me
I would write this as:
Insert Into #AddressRecordsToPurge (GUIDValue, GuidColumn, GuidTable)
Select AccountGUID, 'AccountGUID', 'PREVIOUSLENDERSREF'
from APPLICATIONCONTRACT
where ApplicationNumber = #ApplicationNumber and
AccountGUID IS NOT NULL;
Notes:
This explicitly lists the columns being inserted.
The identity column is not in the list, so it will get the default value.
There is no need for values, just insert . . . select.
As for your code, you need to remember that a subquery always needs to be surrounded by its own set of parentheses.
Alias string names as column names. When you declare a table variable you do not need to mention column names for insert unless you are inserting into few columns. Identity column will automatically populate.
DECLARE #AddressRecordsToPurge TABLE
(
RowID INT NOT NULL PRIMARY KEY IDENTITY(1,1),
GUIDValue Nvarchar(max) NOT NULL,
GuidColumn Nvarchar(max) NOT NULL,
GuidTable Nvarchar(max) NOT NULL
)
Insert Into #AddressRecordsToPurge
SELECT
AccountGUID AS GUIDValue
,'AccountGUID' AS GuidColumn
,'PREVIOUSLENDERSREF' AS GuidTable
FROM APPLICATIONCONTRACT
WHERE ApplicationNumber =#ApplicationNumber AND AccountGUID IS NOT NULL
Try To This Way:
DECLARE #AddressRecordsToPurge TABLE
(
RowID INT NOT NULL
PRIMARY KEY
IDENTITY(1, 1) ,
GUIDValue NVARCHAR(MAX) NOT NULL ,
GuidColumn NVARCHAR(MAX) NOT NULL ,
GuidTable NVARCHAR(MAX) NOT NULL
)
INSERT INTO #AddressRecordsToPurge
( GUIDValue ,
GuidColumn ,
GuidTable
)
SELECT AccountGUID ,
'AccountGUID' ,
'PREVIOUSLENDERSREF'
FROM APPLICATIONCONTRACT AS artp
WHERE ApplicationNumber = #ApplicationNumber
AND AccountGUID IS NOT NULL

Insert multiple records using stored procedure

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

How to group several INSERTs?

I'm inserting data from one table into several others. The first insert will create a new userid. This new userid will be used in succeeding inserts. I will also continue inserting username from the source table into other tables. The chain of inserts below are for one user. There will be probably 2000 users involved.
I'm familiar with how this can be done using a cursor. Is there some other way to do this chain of inserts without a cursor?
insert into table 1 using #username and #firstname from source table
insert into table 2 using userid generated from table 1 (userid1)
insert into table 3 using #username and userid1
insert into table 4 using userid1
You can use the Output Clause of an Insert statement to capture generated Ids in bulk.
For example:
Create Table dbo.Source (
FirstName nvarchar(100),
LastName nvarchar(100)
);
Create Table dbo.Attrs (
Id int Identity Not Null Primary Key,
Name nvarchar(100) Not Null,
DefaultVal nvarchar(100)
);
Create Table dbo.Table1 (
Id Int Identity Not Null Primary Key,
FirstName nvarchar(100),
LastName nvarchar(100)
);
Create Table dbo.Table2 (
Id int Identity Not Null Primary Key,
Table1ID int Not Null Foreign Key References dbo.Table1 (Id),
AttrId int Not Null Foreign Key References dbo.Attrs (Id)
);
Insert Into dbo.Source Values
(N'Mickey', N'Mouse'),
(N'Donald', N'Duck'),
(N'Goofy', Null);
Insert Into dbo.Attrs Values
('Size', 'Small'),
('Wings', 'No');
Declare #Temp1 Table (Id Int, FirstName nvarchar(100), LastName nvarchar(100))
Declare #Temp2 Table (Id int, Table1ID int, AttrId int)
Insert Into dbo.Table1
(FirstName, LastName)
Output
inserted.Id, inserted.FirstName, inserted.LastName
Into
#Temp1
Select
FirstName, LastName
From
dbo.Source
Insert Into dbo.Table2
(Table1ID, AttrId)
Output
inserted.Id, Inserted.Table1ID, Inserted.AttrID
Into
#Temp2
Select
t.Id,
a.Id
From
#Temp1 t
Cross Join
dbo.Attrs a
Select * From #Temp2
http://sqlfiddle.com/#!3/31110/3

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)