getting the last inserted id from previous insert statement - sql

I am having a stored procedure with two insert statement, where I want to insert the ID of the first insert statement into the second one.
CREATE PROC [dbo].[Log_Action]
#action_description VARCHAR(MAX),
#creator_id INT,
#entity VARCHAR(50),
#entity_identifier UNIQUEIDENTIFIER
AS
BEGIN
DECLARE #return_value BIT;
BEGIN TRY
INSERT INTO Action_Lookup (action_description)
VALUES (#action_description);
INSERT INTO Audit ([user_id], action_id, CREATED, [guid], entity, entity_identifier)
VALUES (#creator_id, SCOPE_IDENTITY(), GETDATE(), NEWID(), #entity, #entity_identifier);
SET #return_value = 1;
RETURN #return_value;
END TRY
BEGIN CATCH
SET #return_value = 0;
RETURN #return_value;
END CATCH
END
the problem that SCOPE_IDENTITY() returns null, I also tried ##IDENTITY and IDENT_CURRENT but non works.

Try output clause:
CREATE PROC [dbo].[Log_Action]
#action_description VARCHAR(MAX),
#creator_id INT,
#entity varchar(50),
#entity_identifier uniqueidentifier
AS
BEGIN
DECLARE #return_value bit;
BEGIN TRY
INSERT INTO Action_Lookup (action_description)
OUTPUT
#creator_id,
inserted.[id], -- in [] there should be actual name of identity column
GETDATE(),
NEWID(),
#entity,
#entity_identifier
INTO Audit ([user_id], action_id, created, [guid], entity, entity_identifier)
VALUES (#action_description);
set #return_value = 1;
return #return_value;
END TRY
BEGIN CATCH
set #return_value = 0;
return #return_value;
END CATCH
END

Related

Stored procedure in SQL Server does not return a result set when called by java

I have the following stored procedure and my goal is to return a result set from it, using the query "select * from #justTmp"
create procedure spAddPerson
#ID int,
#Name nvarchar(50)
as
begin
create table #justTmp
(
num int primary key,
justName nvarchar(50)
)
if #ID in (select C.ContributorID
from Contributors C)
begin
insert into #justTmp
values (#ID, #Name)
end
select *
from #justTmp
end
And this is my java code
CallableStatement cstmt = null;
ResultSet rs = null;
cstmt=conn.prepareCall("{ call spAddPerson(?,?) }");
cstmt.setInt(1, 1);
cstmt.setString(2, "MyName");
cstmt.execute();
rs=cstmt.getResultSet();
int first=rs.getInt(1);
String second=rs.getString(2);
For some reason, whenever I run it, and the above stored procedure is called, I get an exception that says
The statement did not return a result set
when the
rs = cstmt.getResultSet()
code is executed.
Any idea how to fix this so a result set would return and not null?
Thanks in advance
Try this :
create proc spAddPerson
#ID int,
#Name nvarchar(50)
as
begin
SET NOCOUNT ON
...
There are multiple ways but try this once:
create proc spAddPerson
#ID int,
#Name nvarchar(50)
as
begin
SET NOCOUNT ON;
create table #justTmp
(
num int primary key,
justName nvarchar(50)
)
if #ID in
(
select C.ContributorID
from Contributors C
)
begin
insert into #justTmp
values(#ID,#Name)
end
select *
from #justTmp
RETURN
end
On your java code change
call spAddPerson
To
exec spAddPerson

SQL Server Trigger containing one or two cursors

I am trying to create a cursor, or cursors, inside of a trigger. What I need to do is when one field in a table is updated, I have to have one cursor or two cursors iterate through and record all of the fields in a table and insert the old and new values into a table.
Here is the code I currently have. This code iterates through the new values in the inserted table correctly, but does not iterate through the old values, in the deleted table.
ALTER TRIGGER [dbo].[Audit_Emp_Trigger]
ON [dbo].[EMPLOYEE]
AFTER UPDATE, DELETE
AS
BEGIN
--Set the fields that we will need in this trigger
DECLARE #OldLName NVARCHAR(50);
DECLARE #NewLName NVARCHAR(50);
DECLARE #OldSSN INT;
DECLARE #NewSSN INT;
DECLARE #OldDno INT;
DECLARE #NewDno INT;
DECLARE #Fname NVARCHAR(50);
DECLARE #Mname NVARCHAR(50);
DECLARE #BDate DATE;
DECLARE #Address NVARCHAR(100);
DECLARE #Sex CHAR(1);
DECLARE #Salary INT;
DECLARE #SuperSSN INT;
--Only execute the trigger if the Dno field was updated or deleted
IF UPDATE(Dno)
BEGIN
--If this is an insert operation, we will be inserting a new Dno value
SELECT #OldLName = D.LName FROM deleted D
SELECT #OldSSN = D.Ssn FROM deleted D
SELECT #OldDno = D.Dno FROM deleted D
DECLARE InsertCursor CURSOR FOR SELECT Fname, Minit, Lname, Ssn, Bdate, Address, Sex, Salary, Super_ssn, Dno FROM inserted
OPEN InsertCursor
FETCH NEXT FROM InsertCursor INTO #Fname, #Mname, #NewLName, #NewSSN, #BDate, #Address, #Sex, #Salary, #SuperSSN, #NewDno
WHILE ##FETCH_STATUS = 0
BEGIN
--If the Audit_Emp_Record table does not exist already, we need to create it
IF OBJECT_ID('dbo.Audit_Emp_Record') IS NULL
BEGIN
--Table does not exist in database, so create table
CREATE TABLE Audit_Emp_Record
(
date_of_change smalldatetime,
old_Lname varchar (50),
new_Lname varchar (50),
old_ssn int,
new_ssn int,
old_dno int,
new_dno int
);
--Once table is created, insert the values of the update operation into the table
INSERT INTO Audit_Emp_Record(date_of_change, old_Lname, new_Lname, old_ssn, new_ssn, old_dno, new_dno) VALUES(GETDATE(), #OldLName, #NewLName, #OldSSN, #NewSSN, #OldDno, #NewDno)
END
ELSE
BEGIN
--The table already exists, so simply insert the new values of the update operation into the table
INSERT INTO Audit_Emp_Record(date_of_change, old_Lname, new_Lname, old_ssn, new_ssn, old_dno, new_dno) VALUES(GETDATE(), #OldLName, #NewLName, #OldSSN, #NewSSN, #OldDno, #NewDno)
END
FETCH NEXT FROM InsertCursor INTO #Fname, #Mname, #NewLName, #NewSSN, #BDate, #Address, #Sex, #Salary, #SuperSSN, #NewDno
END
END
END

How to update SQL field using function and stored procedure?

What I want to do is to update column (NewID) in my table (SampleTable) with the following code, but it's not working.. can somebody help me please? Whats wrong with it?
I have the table 'SampleTable' wich has the fields 'NewID' and 'OldID'.
UPDATE SampleTable SET NewID = dbo.fn_DoStuff(OldID) <-- Not working
My function:
ALTER FUNCTION [dbo].[fn_DoStuff]
(
#int oldid
)
RETURNS int
AS
BEGIN
DECLARE #returnValue int
EXEC #returnValue = dbo.spc_DoStuff #oldid
RETURN #returnValue
END
My stored procedure:
SampleTable1 has the columns ID, SomeColName.
ALTER PROCEDURE [dbo].[spc_GeraAtriðisorðalistaÚrAtriðisorði]
(
#oldid int
)
AS
BEGIN
DECLARE #returnValue int
INSERT INTO SampleTable1 (SomeColName) VALUES (null)
SET #returnValue = ##IDENTITY
INSERT INTO SampleTable2 (SomeColName1, SomeColName2) VALUES (#returnValue, #oldid)
SELECT #returnValue AS RetVal
END
You have 2 problems, the first is you cannot call a stored procedure inside a function, nor can you perform your insert within a function.
The second problem is that even if you could call a stored procedure inside a function, you are not returning the value from the procedure correctly. You would need something like:
CREATE TABLE dbo.T (ID INT IDENTITY, Filler CHAR(10));
GO
CREATE PROCEDURE dbo.Test
AS
DECLARE #i INT;
INSERT dbo.T (Filler) VALUES (NULL);
RETURN SCOPE_IDENTITY();
GO
Note the use of the RETURN statement, if you don't use this the default return value is 0
Then you can use:
DECLARE #i INT;
EXECUTE #i = dbo.Test;
SELECT ReturnVal = #i;
*Note, I have replaced ##IDENTITY with SCOPE_IDENTITY(), ##IDENTITY is rarely the correct function to use*
Example on SQL Fiddle
With your solution GarethD I could still not call the function like I wanted to
UPDATE SampleTable SET NewID = dbo.fn_DoStuff(OldID).
Your code helped me though to start thinking another way. Now I'm using a cursor and a while loop and it works perfectly. See my solution below:
DECLARE #OldID AS INT
DECLARE Upd_CURSOR FOR
SELECT OldID
FROM dbo.SampleTable
WHERE OldID is not null
FOR UPDATE OF NewID
OPEN Upd_CURSOR;
FETCH NEXT FROM Upd_CURSOR INTO #OldID
WHILE ##FETCH_STATUS = 0
BEGIN
DECLARE #returnValue int;
INSERT INTO SampleTable1 (SomeColName) VALUES (null);
SET #returnValue = SCOPE_IDENTITY();
INSERT INTO SampleTable2 (SomeColName1, SomeColName2) VALUES (#returnValue, #OldID)
UPDATE dbo.SampleTable SET NewID = #returnValue WHERE CURRENT OF Upd_CURSOR;
FETCH NEXT FROM Upd_CURSOR INTO #OldID;
END;
CLOSE Upd_CURSOR;
DEALLOCATE Upd_CURSOR;
GO

Yet another primary key exception

Last year I ask this question: What could be causing the primary key exception?
But I still have another error in this stored procedure: randomly I get
INSERT EXCEPTION WITH FOREIGN KEY "FK_Sessions" WITH TABLE
"Sessions", column "id".
CREATE PROCEDURE [dbo].[MyProcedure]
#sessionId varchar(512),
#variable varchar(350),
#value image
AS
BEGIN
BEGIN TRAN
DECLARE #result int = 0;
DECLARE #locked bit;
IF (SELECT COUNT(*) FROM Sessions WITH(ROWLOCK,HOLDLOCK) WHERE id = #sessionId) = 0
BEGIN
SET #result = -1;
END
ELSE BEGIN
DELETE Variables WITH(ROWLOCK,HOLDLOCK) WHERE sessionId = #sessionId AND variable = #variable
IF #value IS NOT NULL
BEGIN
INSERT Variables VALUES(#sessionId, #variable, #value, 0)
END
END
COMMIT TRAN
RETURN #result
END
Any ideas? Thanks again

SQL Server: Return uniqueidentifier from stored procedure

Can I return UNIQUEIDENTIFIER from a stored procedure using the RETURN statement or is it only by using the OUTPUT statement?
i.e to return the PersonID UNIQUEIDENTIFIER:
CREATE PROCEDURE CreatePerson
#Name NVARCHAR(255),
#Desc TEXT
AS
DECLARE #Count INT
DECLARE #JobFileGUID UNIQUEIDENTIFIER
-- Check if job exists?
SET #Count = (SELECT COUNT(Name) AS Name FROM Person WHERE Name=#Name)
IF #Count < 1
BEGIN
SET #PersonGUID = NEWID();
INSERT INTO Person
(PersonID, Name, [Desc])
VALUES (#PersonGUID, #Name, #Desc)
END
SELECT #PersonGUID = Person.PersonID
FROM Person
WHERE Name = #Name
RETURN #PersonGUID
GO
Thanks
In stored procedure - only using the OUTPUT statement. In function - return.
Use:
CREATE PROCEDURE CreatePerson
#Name NVARCHAR(255),
#Desc TEXT,
#PersonGUID UNIQUEIDENTIFIER OUTPUT
AS
BEGIN
SET #PersonGUID = ...
END
How to call:
DECLARE
#name NVARCHAR(255),
#desc TEXT,
#personGUID UNIQUEIDENTIFIER
SET #name = 'Bob'
SET #desc = 'One handsome man.'
EXEC [Database].[schema].CreatePerson #name, #desc, #personGUID OUTPUT
From the documentation you can actually see that a return in a stored procedure is actually used as a response code, hence you get the exception when trying to return a uniqueidentifier.
https://learn.microsoft.com/en-us/sql/relational-databases/stored-procedures/return-data-from-a-stored-procedure?view=sql-server-ver16#return-data-using-a-return-code
How I solved it, is by just performing a SELECT after the insert of the generated unique identifier.
DECLARE #ReportId UNIQUEIDENTIFIER;
SET #ReportId = NEWID();
INSERT INTO [dbo].[Report]
([ReportId]
,[ReportName])
VALUES
(#ReportId
,#ReportName)
SELECT #ReportId as ReportIdInternal
You'll have to see how to perform that with multiple selects though.
CREATE TABLE [dbo].[tbl_Clients]( [ClientID] [uniqueidentifier] NULL, [ClientName] varchar NULL, [ClientEnabled] [bit] NULL ) ON [PRIMARY]
GO
CREATE PROCEDURE [dbo].[sp_ClientCreate] #in_ClientName varchar(250) = "New Client 123", #in_ClientEnabled bit, #out_ClientId uniqueidentifier OUTPUT AS
SET #out_ClientId = NEWID();
INSERT INTO tbl_Clients(ClientId, ClientName, ClientEnabled) VALUES( #out_ClientId, #in_ClientName, #in_ClientEnabled)
DECLARE #return_value int, #out_ClientId uniqueidentifier
EXEC #return_value = [dbo].[sp_ClientCreate] #in_ClientName = N'111', #in_ClientEnabled = 1, #out_ClientId = #out_ClientId OUTPUT
SELECT #out_ClientId as N'#out_ClientId'
SELECT 'Return Value' = #return_value
GO
Result:-59A6D7FE-8C9A-4ED3-8FC6-31A989CCC8DB