MSSQL-server Stored procedure inserting only last Row - sql

I have created a stored procedure to Move all items from IDx to IDz and as it does that it has to log some data of each row it moves. The procedure moves rows from ID< to IDz without any problems. But when it has to log the information it only logs the last row that is moved. What am i doing wrong?
this is my code:
USE [TrackIT_Test]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[MoveCustIDAndAlias]
-- Add the parameters for the stored procedure here
#SourceAdrID int,
#TargetAdrID int,
#Username varchar(50)
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
declare #custID varchar(50)
set #custID = ''
declare #alias varchar(50)
set #alias = ''
-- Insert statements for procedure here
Select #custID = (CustID), #alias = (Alias) from dbo.Alias where AdrID = #SourceAdrID;
Insert into dbo.AliasMoveLog (CustID, Alias, Username) VALUES (#custID, #alias, #Username);
UPDATE dbo.Alias SET AdrID = #TargetAdrID WHERE AdrID = #SourceAdrID;
Can anyone help ?

Yes, I see your problem.
When you're using variable and set the variable value with select, it will store only the value in the last row.
You can try this to prove it:
CREATE TABLE tbl
(
col1 INT
);
INSERT INTO tbl VALUES (1);
INSERT INTO tbl VALUES (2);
INSERT INTO tbl VALUES (3);
DECLARE #x int
SELECT #x = col1 FROM tbl
PRINT #x -- will print 3
For your sp, try to change this line:
Select #custID = (CustID), #alias = (Alias) from dbo.Alias where AdrID = #SourceAdrID;
Insert into dbo.AliasMoveLog (CustID, Alias, Username) VALUES (#custID, #alias, #Username);
to:
Insert into dbo.AliasMoveLog (CustID, Alias, Username)
Select CustID, Alias, #Username from dbo.Alias where AdrID = #SourceAdrID;
More detail: SELECT #local_variable

Well you cannot bulk insert values once you declare the variable like that.
Simple way is to do it this way:
INSERT INTO dbo.AliasMoveLog (CustID, Alias, Username)
SELECT CustID, Alias, #Username FROM dbo.Alias WHERE AdrID = #SourceAdrID;

Related

Return inserted row from stored procedure

I have the following stored procedure
CREATE PROCEDURE [dbo].[spInsert]
#name nvarchar(128),
AS
insert into NameIdentifier
( Name, Identifier)
values
( #name, NEWID());
SELECT #new_identity = SCOPE_IDENTITY()
SELECT * FROM NameAge where Id = #new_identity
Is there are a more efficient way to return the last inserted record complete with id and associated data?
Use Insertedwithin output clause,
As the follwoing:
CREATE PROCEDURE [dbo].[spInsert]
#name nvarchar(128),
AS
DECLARE #MyTableVar table(
Name varchar(50),
Identifier uniqueidentifier
;
insert into NameIdentifier
( Name, Identifier)
values
( #name, NEWID());
OUTPUT INSERTED.Name, INSERTED.Identifier
INTO #MyTableVar
SELECt Name,Identifier from #MyTableVar
Refreance:
Best way to get identity of inserted row?
SCOPE_IDENTITY() is used to get the last generated Identity value in an identity column in your scope , For GUID values either you get the guid before you insert it like I have done in the code below , or you use OUTPUT clause to get the guid generated by the Insert statement.
CREATE PROCEDURE [dbo].[spInsert]
#name nvarchar(128)
AS
BEGIN
SET NOCOUNT ON;
Declare #NewID UNIQUEIDENTIFIER = NEWID();
insert into NameIdentifier ( Name, Identifier)
values( #name, #NewID);
SELECT * FROM NameAge where Id = #NewID;
END
This should give you your desired functionality.
CREATE PROCEDURE [dbo].[spInsert]
#name nvarchar(128),
#Ret int Output
AS
BEGIN
insert into NameIdentifier
( Name, Identifier)
values
( #name, NEWID());
END
SET #Ret = ##IDENTITY
EDIT: This will return the id of your newly inserted row.
You can achieve this by using the output clause of SQL Server, you can read more about this here
if exists (select 1 from sys.tables where name = 'NameIdentifier ')
drop table NameIdentifier
create table NameIdentifier
(
id BIGINT IDENTITY(1,1)
,Name VARCHAR(100)
,Identifier uniqueidentifier
)
DECLARE #id TABLE
(
ID BIGINT
)
INSERT INTO NameIdentifier (Name,Identifier)
OUTPUT INSERTED.id INTO #id
VALUES('abcd',NEWID())
SELECT * FROM NameIdentifier N, #id I where N.id = I.id

SQL Server: How to use result from one INSERT for another INSERT

I have a stored procedure that is meant to update two tables at once.
My problem here is that the first table has an auto-incrementing ID column ("commentID") and my second table has a relationship on this so I need the newly created ID from the first INSERT in order to make the second INSERT.
I tried the following which I can save without errors but it doesnt execute as it should and does not update the tables as intended.
Can someone tell me what I am doing wrong here ?
My SQL:
ALTER PROCEDURE [dbo].[MOC_UpdateComment]
#imgID int,
#commentID int = '999999',
#comment nvarchar(1000),
#lastUpdate nvarchar(50),
#modBy varchar(50)
AS
BEGIN
DECLARE #temp AS TABLE
(
commentID int
)
SET NOCOUNT ON;
BEGIN TRANSACTION;
INSERT INTO MOC_BlogComments
(
imgID,
comment
)
OUTPUT inserted.commentID INTO #temp(commentID)
SELECT #imgID,
#comment
INSERT INTO MOC_LogComments
(
commentID,
lastUpdate,
modTime,
modBy
)
SELECT commentID,
#lastUpdate,
GETDATE(),
#modBy
FROM #temp
COMMIT TRANSACTION;
END
DECLARE #imgID INT,
#commentID INT = '999999',
#comment NVARCHAR(1000),
#lastUpdate NVARCHAR(50),
#modBy VARCHAR(50)
DECLARE #MORC_BlogComments AS TABLE
(
id INT IDENTITY(1, 1) NOT NULL,
imgid INT,
comment VARCHAR(100)
)
DECLARE #MORC_LogComments AS TABLE
(
commentid INT,
lastupdate DATETIME,
modtime DATETIME,
modby VARCHAR(100)
)
DECLARE #TEMP AS TABLE
(
commentid INT
)
SET nocount ON;
BEGIN TRANSACTION;
INSERT INTO #MORC_BlogComments
(imgid,
comment)
output inserted.id
INTO #TEMP(commentid)
VALUES (#imgID,
#comment)
INSERT INTO #MORC_LogComments
(commentid,
lastupdate,
modtime,
modby)
SELECT commentid,
#lastUpdate,
Getdate(),
#modBy
FROM #temp
SELECT *
FROM #MORC_LogComments
Function SCOPE_IDENTITY() returns the identity of last insert operation. You can use it to get the value which you need to use in second INSERT statement
You can use it like this in your statement:
INSERT INTO MORC_BlogComments (imgID, comment)
VALUES (#imgID, #comment)
INSERT INTO MORC_LogComments (commentID, lastUpdate, modTime, modBy)
VALUES (SCOPE_IDENTITY(), #lastUpdate, GETDATE(), #modBy)

how to insert autoNumbersCode into another table

I have 2 tables with some fields like this:
CompanyTable (companyCode, name, contactCode)
ContactTable (contactCode, address, phone)
CompanyTable.contactCode is foregin key that assign to ContactTable.contactCode
and also CompanyTable.companyCode and CompanyTable.contactCode are autoNumbers.
when I insert new record in contactTable, I want to insert it's contactCode into CompanyTable.contactCode like this:
insert into contactTable ( address, phone) values ('x', 'x')
update companyTable set company.contactCode = ---------
How to get latest identity value after insert query?
Thanks
Use ##IDENTITY to retrieve latest generated Identity value.
execute it after your insert query.
insert into contactTable ( address, phone) values ('x', 'x')
DECLARE #contactCode INT;
SELECT #contactCode = ##IDENTITY;
update companyTable set company.contactCode = #contactCode Where companyCode=1
You can add a trigger to add the contactCode. It would look like this:
CREATE TRIGGER trgUpdateCompanyTable
ON dbo.ContactTable
AFTER INSERT
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
DECLARE #id INTEGER
SET #id = (SELECT IDENT_CURRENT('ContactTable'))
INSERT INTO CompanyTable (contactCode)
VALUES (#id)
END
GO

Passing multiple parameters into a Table valued function

I have a table valued function as below. When I am trying to pass more than one parameter at the same time I am getting a error like "Function has too many arguments specified" .
CREATE FUNCTION [dbo].[GetCompanyUsers](#CompanyId BIGINT)
RETURNS #Users TABLE (Id BIGINT,Contact NVarchar(4000))
AS
BEGIN
INSERT INTO #Users(Id,Contact)
SELECT [Id]
,ISNULL([FirstName],'')+' ' +ISNULL([LastName],'') AS [Contact]
FROM [dbo].[CompanyAddressesContacts]
WHERE [CompanyId]=#CompanyId
ORDER BY ISNULL([FirstName],'')+' ' +ISNULL([LastName],'')
RETURN
END
What modifications I require in the above code so that it allows multiple values and I need to use the function in a "WHERE" condition in my dataset.
WHERE(Document_RFIs.CreatedBy IN
(SELECT Id FROM dbo.GetCompanyUsers(#CompanyId)))
This may help (but the fundamental problem is - passing a comma delimited string is something to be avoided unless absolutely necessary - which explains why you have received so few answers):-
--set nocount on
--create table #Document_RFIs (
-- CreatedBy varchar(50),
-- columna varchar(50),
-- columnb varchar(50),
-- columnc varchar(50)
--)
--insert into #Document_RFIs values
-- ('albert einstein','another','value',null),
-- ('marie curie','some',null,'tuna'),
-- ('isaac newton','why','not','provide'),
-- ('kepler','some','test','data'),
-- ('robert boyle','with','your','question'),
-- ('john dalton','it',null,'would'),
-- ('enrico fermi','make','helping','you'),
-- ('peter higgs','so','much','easier')
--create table #CompanyAddressesContacts (
-- companyid int,
-- firstname varchar(50),
-- lastname varchar(50)
--)
--insert into #CompanyAddressesContacts values (22,'albert','einstein')
--insert into #CompanyAddressesContacts values (23,'marie','curie')
--insert into #CompanyAddressesContacts values (23,'isaac','newton')
--insert into #CompanyAddressesContacts values (24,null,'kepler')
--insert into #CompanyAddressesContacts values (25,'robert','boyle')
--insert into #CompanyAddressesContacts values (25,'enrico','fermi')
--insert into #CompanyAddressesContacts values (26,'peter','higgs')
declare #ids varchar(1024)
set #ids='23,24,25'
create table #id (
companyid int
)
declare #pos int
while DATALENGTH(#ids)>0 begin
set #pos=charindex(',',#ids)
if #pos>0 begin
insert into #id values (left(#ids,#pos-1))
set #ids=SUBSTRING(#ids,#pos+1,DATALENGTH(#ids))
end else begin
insert into #id values (#ids)
set #ids=''
end
end
select d.*
from #Document_RFIs d
where exists(
select cac.*
from #CompanyAddressesContacts cac
join #id i on i.companyid=cac.companyid
where isnull(cac.firstname+' ','')+isnull(cac.lastname,'')=d.CreatedBy
)
--drop table #id
--drop table #Document_RFIs
--drop table #CompanyAddressesContacts
I would do something like this:
First convert your #CompanyId to rows
WITH CompanyIds AS (
SELECT Id
FROM CompanyTable -- Same as the source of the #CompanyId
WHERE Id IN (#CompanyId)
)
Then extract all users
,Users AS (
SELECT UserId
FROM CompanyIds
CROSS APPLY (
SELECT Id AS UserId
FROM dbo.GetCompanyUsers(CompanyIds.Id)
) AS CA1
)
And then use it in the where statement
WHERE Document_RFIs.CreatedBy IN (SELECT UserId
FROM Users)

Calling stored procedure from another stored procedure SQL Server

I have 3 insert stored procedures each SP inserts data in 2 different tables
Table 1 Table 2
idPerson idProduct
name productName
phoneNumber productdescription
FK-idProduct
SP for table 1 SP for table 2
create procedure test1 create procedure test2
WITH WITH
EXECUTE as caller EXECUTE as caller
AS AS
declare declare
#idPerson int, #idProduct int,
#name varchar(20), #productName varchar(50),
#phone varchar(20) #productoDescription varchar(50)
SET nocount on; SET nocount on;
Begin Begin
insert into table1( insert into table2(
idPerson, idProduct,
name, productName,
phone) productDescription)
values( values(
#idPerson, #idProduct,
#name, #productName,
#phone) #productDescription)
end end
I need to call stored procedure test 2 from stored procedure test 1 and insert the FK-ID in the table 1
Simply call test2 from test1 like:
EXEC test2 #newId, #prod, #desc;
Make sure to get #id using SCOPE_IDENTITY(), which gets the last identity value inserted into an identity column in the same scope:
SELECT #newId = SCOPE_IDENTITY()
You could add an OUTPUT parameter to test2, and set it to the new id straight after the INSERT using:
SELECT #NewIdOutputParam = SCOPE_IDENTITY()
Then in test1, retrieve it like so:
DECLARE #NewId INTEGER
EXECUTE test2 #NewId OUTPUT
-- Now use #NewId as needed
First of all, if table2's idProduct is an identity, you cannot insert it explicitly until you set IDENTITY_INSERT on that table
SET IDENTITY_INSERT table2 ON;
before the insert.
So one of two, you modify your second stored and call it with only the parameters productName and productDescription and then get the new ID
EXEC test2 'productName', 'productDescription'
SET #newID = SCOPE_IDENTIY()
or you already have the ID of the product and you don't need to call SCOPE_IDENTITY() and can make the insert on table1 with that ID