Ninja kargeti
Ninja kargeti

Reputation: 161

Insert Query to insert multiple rows in a table via select and output clause. SQL Server 2008

I have a created a stored procedure (please ignore syntax errors)

alter proc usp_newServerDetails
   (@appid int, @envid int, @serType varchar(20), @servName varchar(20))
as
    declare @oTbl_sd table (ID int)
    declare @outID1
    declare @oTbl_cd table (ID int)
    declare @outID2

    begin Transaction
        insert into server_details(envid, servertype, servername)
        output inserted.serverid into @oTbl_sd(ID)
        values(@envid, @serType, @servName)

        select @outID1 = ID from @oTbl_sd

        insert into configdetails(serverid, servertype, configpath, configtype)
        output inserted.configid into @oTbl_cd(ID)
        (select @outID1, cm.servertype, cm.configpath, cm.configtype 
         from configpthmaster cm 
         where cm.appid = @appid )

        select @outID2 = ID from @oTbl_cd

        insert into configkeydetails(confiid, keyname)
        output inserted.Keyid into @oTbl_ckd(ID)
        (select @outID2, cm.key 
         from configpthmaster cm 
         where cm.appid = @appid)

    begin 
    commit
    end

server_details table has an identity column ID with is auto-generated ie. @outID1 and first insert query inserts only 1 row.

configpthmaster table is not related to any other table directly and has 2 unique data rows, which I want to fetch to insert data into other tables, one by one during insertion.

The second insert query fetch data from configpthmaster table and insert 2 rows in configdetails while generating (auto-generated) ID ie. @outID2.

It also has a FK mapped to server_details.

The problem is "@outID2" giving last inserted ID only (ie. if two id generated 100,101 i am getting 101) which eventually on 3rd insertion, inserting 2 rows with same id 101 only but i want the insertion should be linear. i.e one for 100 and other for 101.

If zero rows affected while insertion how to rollback the transaction?

How can I achieve these requirements? Please help.

Upvotes: 2

Views: 1752

Answers (2)

Unnikrishnan R
Unnikrishnan R

Reputation: 5031

Change your procedure like below,and try again.

ALTER PROCEDURE usp_newServerDetails(@appid int, @envid int,@serType varchar(20),@servName varchar(20))
    AS
BEGIN
  BEGIN TRY

   DECLARE @Output TABLE (ID int,TableName VARCHAR(50),cmKey VARCHAR(50)) --table variable for keeping Inserted ID's

        BEGIN TRAN


         IF EXISTS ( SELECT 1 FROM configpthmaster cm  WHERE cm.appid = @appid ) 
                        AND  ( SELECT 1 FROM configkeydetails ck  WHERE ck.appid = @appid ) --add a conditon to satisfy the valid insertions

         BEGIN

            INSERT INTO server_detials(envid,servertype,servername)
                OUTPUT inserted.serverid,'server_detials',NULL INTO @Output(ID,TableName,cmKey )
            VALUES(@envid ,@serType ,@servName)

            INSERT INTO configdetails(serverid,servertype,configpath,configtype)
                OUTPUT inserted.configid,'configdetails',cm.Key INTO @Output(ID,TableName,cmKey )
            SELECT t.ID,cm.servertype,cm.configpath,cm.configtype 
            FROM configpthmaster cm 
              CROSS APPLY (SELECT ID FROM @Output WHERE TableName='server_detials')t
            WHERE cm.appid = @appid

            INSERT INTO configkeydetails(configId,keyname)
            SELECT ID,cmKey FROM @Output 
            WHERE TableName='configdetails'

        END

       COMMIT TRAN
  END TRY

    BEGIN CATCH

        IF @@TRANCOUNT > 0 
        ROLLBACK 

    END CATCH

END

Upvotes: 2

Mr.J
Mr.J

Reputation: 440

Could you try this solution?

alter proc usp_newServerDetails(@appid int, @envid int,@serType varchar(20),@servName varchar(20))
as
declare @oTbl_sd table (ID int)
declare @outID1
declare @oTbl_cd table (ID int)
declare @outID2

begin Transaction

insert into server_detials(envid,servertype,servername)
output inserted.serverid into @oTbl_sd(ID)
values(@envid ,@serType ,@servName)

select @outID1 = ID from @oTbl_sd

insert into configdetails(serverid,servertype,configpath,configtype)
output inserted.configid into @oTbl_cd(ID)
(select @outID1 ,cm.servertype,cm.configpath,cm.configtype from configpthmaster cm where cm.appid = @appid )

select @outID2 = ID from @oTbl_cd
insert into configkeydetails(confiid,keyname)
output inserted.Keyid into @oTbl_ckd(ID)
(select  isnull(replace(stuff((SELECT inserted.configid FOR xml path('')), 1, 1, ''), '&', '&'), '')  ,cm.key, from configpthmaster cm where cm.appid = @appid )

begin 
commit
end

I just added STUFF in your code.

The STUFF function inserts a string into another string.

Do take note that using STUFF drastically slows the processing time of the code.

for more information about STUFF

Upvotes: 0

Related Questions