SQL Server Stored Procedure Update and Return Single Value - sql

I need to call a stored procedure, give it a report id (int) and have it update a report table with a confirmation number (varchar) (confirmation # generated in the stored procedure) and return the confirmation number (i will need it to return it to a web service/website).
My stored procedure code:
DECLARE PROCEDURE [dbo].[spUpdateConfirmation]
#ReportID int
AS
BEGIN
Declare #Confirmation varchar(30) = replace(replace(replace(convert(varchar(16),CURRENT_TIMESTAMP,120),'-',''),' ',''),':','')+convert(varchar(24),#ReportID)
PRINT #Confirmation
UPDATE Report
SET Confirmation = #Confirmation
WHERE ReportID = #ReportID;
RETURN #Confirmation
END
My call to the stored procedure:
execute [spUpdateConfirmation] 2
I confirmed in the table the value was inserted but I get this error message:
2013050219072
(1 row(s) affected)
Msg 248, Level 16, State 1, Procedure spUpdateConfirmation, Line 12
The conversion of the varchar value '2013050219072' overflowed an int column.
The 'spUpdateConfirmation' procedure attempted to return a status of NULL, which is not allowed. A status of 0 will be returned instead.
Question: What did I do wrong?
I understand what overflow is, the value is too large for an int, but I used the convert to varchar, inserted to table column type varchar(30)
I also tested this statement in SQL and it works fine:
print replace(replace(replace(convert(varchar(16),CURRENT_TIMESTAMP,120),'-',''),' ',''),':','')+convert(varchar(24),2)
It returns: 2013050219162

RETURN from a stored procedure only allows integer values. Specifically, the documentation states:
RETURN [ integer_expression ]
If you want to return a varchar value, you can use an output parameter
CREATE PROCEDURE [dbo].[spUpdateConfirmation]
#ReportID int, #Confirmation varchar(30) output
AS
--BEGIN
SET #Confirmation = replace(replace(replace(convert(varchar(16),CURRENT_TIMESTAMP,120),'-',''),' ',''),':','')+convert(varchar(24),#ReportID)
--PRINT #Confirmation
UPDATE Report
SET Confirmation = #Confirmation
WHERE ReportID = #ReportID;
--RETURN #Confirmation
--END
GO
To be called like this
declare #reportID int; -- set #reportID
declare #confirmation varchar(30);
exec [dbo].[spUpdateConfirmation] #reportID, #confirmation output;
-- #confirmation now contains the value set from the SP call above
A simpler option if you are calling this from C# is to SELECT the output as a single-row, single-column result and use SqlCommand.ExecuteScalar, e.g.
CREATE PROCEDURE [dbo].[spUpdateConfirmation]
#ReportID int
AS
--BEGIN
DECLARE #Confirmation varchar(30);
SET #Confirmation = replace(replace(replace(convert(varchar(16),CURRENT_TIMESTAMP,120),'-',''),' ',''),':','')+convert(varchar(24),#ReportID)
--PRINT #Confirmation
SET NOCOUNT ON; -- prevent rowcount messages
UPDATE Report
SET Confirmation = #Confirmation
WHERE ReportID = #ReportID;
--RETURN #Confirmation
SET NOCOUNT OFF; -- re-enable for the following select
SELECT #Confirmation; -- this is the value you get
--END
GO

Related

How to return an id and use it directly in another stored procedure?

I want his stored procedure to return the inserted id
ALTER PROCEDURE [dbo].[InsertAddress_DBO]
#Name VARCHAR(50)
AS
BEGIN
SET NOCOUNT ON;
INSERT INTO [dbo].[Address]([Address_Name])
OUTPUT INSERTED.Address_Id
VALUES (#Name)
END
This one the same
ALTER PROCEDURE [dbo].[InsertDocumentation_DBO]
#Texte VARCHAR(50)
AS
BEGIN
SET NOCOUNT ON;
INSERT INTO [dbo].[Documentation]([Documentation_Text])
OUTPUT inserted.Documentation_Id
VALUES (#Texte)
END
And this one to use them and return her own -
like using the inserted id to put it into the next stored procedure as a parameter
ALTER PROCEDURE [dbo].[InsertEstablishmentByStrings_DBO]
#Establishment_Name VARCHAR(50),
#Address_Name VARCHAR(50),
#Documentation_Text VARCHAR(50)
AS
BEGIN
SET NOCOUNT ON;
DECLARE #Address_ID INT ,
#Documentation_ID INT
EXEC #Address_ID = [dbo].[InsertAddress_DBO]
#Name = "rue de la banchiesserie 85 Golback"
EXEC #Documentation_ID = [dbo].[InsertDocumentation_DBO]
#Texte = "né en 55555 restaurant fabuleux"
INSERT INTO [dbo].[Establishment]([Establishment_Name],[Address_Id],[Documentation_Id])
OUTPUT inserted.Establishment_Id
VALUES (#Establishment_Name,#Address_ID,#Documentation_ID)
END
However, I always get an error, because the stored procedure doesn't return the id when I execute it.
What is wrong in my code?
I would like to get the code I could use again and again in each stored procedure I have to execute. I already tried ##Identity, indent, scoped,... nothing works.
If you want to return something from stored procedure to the context of SQL query execution you may use a return statement or an output parameter. I would suggest you to use the second option. The first one is generally intended to return status of procedure execution.
ALTER PROCEDURE [dbo].[InsertAddress_DBO]
#Name VARCHAR(50),
#Address_ID INT OUTPUT
AS
BEGIN
SET NOCOUNT ON;
INSERT INTO [dbo].[Address]([Address_Name])
VALUES (#Name)
SET #Address_ID = SCOPE_IDENTITY()
END
Than you can use returned value in your outer procedure
ALTER PROCEDURE [dbo].[InsertEstablishmentByStrings_DBO]
#Establishment_Name VARCHAR(50),
#Address_Name VARCHAR(50),
#Documentation_Text VARCHAR(50)
AS
BEGIN
SET NOCOUNT ON;
DECLARE #Address_ID INT ,
#Documentation_ID INT
EXEC [dbo].[InsertAddress_DBO]
#Address_ID = #Address_ID OUTPUT,
#Name = "rue de la banchiesserie 85 Golback"
...
END
An OUTPUT INSERTED clause you used doesn't returns data to the query execution context but send them to the output stream.
Your stored procedures should look like this, using an OUTPUT parameter, not trying to consume a RETURN value (which should never contain data) using a resultset. Also [don't] [put] [everything] [in] [square] [brackets] [unless] [you] [have] [to], [because] [all] [it] [does] [is] [hamper] [readability], and don't surround string literals with "double quotes" because that means something else in T-SQL.
CREATE OR ALTER PROCEDURE dbo.InsertAddress_DBO
#Name varchar(50),
#Address_Id int OUTPUT
AS
BEGIN
SET NOCOUNT ON;
INSERT dbo.Address(Address_Name)
VALUES (#Name);
SELECT #Address_Id = SCOPE_IDENTITY();
END
GO
CREATE OR ALTER PROCEDURE dbo.InsertDocumentation_DBO
#Texte varchar(50),
#Doc_Id int OUTPUT
AS
BEGIN
SET NOCOUNT ON;
INSERT dbo.Documentation(Documentation_Text)
VALUES (#Texte);
SELECT #Doc_Id = SCOPE_IDENTITY();
END
GO
Now, your main procedure can do this:
CREATE OR ALTER PROCEDURE dbo.InsertEstablishmentByStrings_DBO
#Establishment_Name varchar(50),
#Address_Name varchar(50),
#Documentation_Text varchar(50)
AS
BEGIN
SET NOCOUNT ON;
DECLARE #Address_ID INT ,
#Documentation_ID INT
EXEC dbo.InsertAddress_DBO
#Name = #Address_Name,
#Address_Id = #Address_ID OUTPUT;
EXEC dbo.InsertDocumentation_DBO
#Texte = Documentation_Text,
#Doc_Id = #Documentation_ID OUTPUT;
INSERT dbo.Establishment
(Establishment_Name, Address_Id, Documentation_Id)
OUTPUT inserted.Establishment_Id,
inserted.Address_ID, inserted.Documentation_ID
VALUES (#Establishment_Name,#Address_ID,#Documentation_ID);
END
GO
And you call it like this:
EXEC dbo.InsertEstablishmentByStrings_DBO
#Establishment_Name = 'Gaston''s',
#Address_Name = 'rue de la banchiesserie 85 Golback',
#Documentation_Text = 'né en 55555 restaurant fabuleux';
And get results like this:
Establishment_Id
Address_ID
Documentation_ID
1
1
1
Fully working example on db<>fiddle

How to change data type of output of stored procedure? I want to output money data type but procedure always returns int

This is my procedure:
ALTER PROCEDURE spMaxOfInvoiceTotal
AS
BEGIN
DECLARE #max MONEY
SET #max = (SELECT MAX(InvoiceTotal) FROM Invoices)
PRINT #MAX
RETURN #MAX
END
GO
But when I execute, it returns int not money type.
DECLARE #return_value int
EXEC #return_value = [dbo].[spMaxOfInvoiceTotal]
SELECT 'Return Value' = #return_value
GO
As a result, a value is incorrect. It has to be 37966.19. But procedure returns 37966.
Even if I change #return_value money, I still get int. How to change procedure so return value would be money?
Stored procedure return value is used to return exit code, it is integer.
You should define output parameter
CREATE PROCEDURE mysp
#Maxval MONEY OUTPUT
http://msdn.microsoft.com/en-us/library/ms188655.aspx
What RDBMS is this for? SQL Server?
The value returned from a stored procedure in SQL Server is always INT and you can't change that - it's typically used to convey back a success/failure flag, or a "number of rows affected" information.
If you to "return" a MONEY (or better yet: DECIMAL) value - you can either use an OUTPUT parameter (which works fine for a single value), or you need to return a result set with that value.
So in your case, you could try something like:
CREATE PROCEDURE GetMaxOfInvoiceTotal
#MaxValue DECIMAL(20,4) OUTPUT
AS
BEGIN
SET #MaxValue = (SELECT MAX(InvoiceTotal) FROM Invoices)
END
GO
and then call this stored procedure like this:
DECLARE #RC INT
DECLARE #MaxValue DECIMAL(20,4)
EXECUTE #RC = [dbo].[GetMaxOfInvoiceTotal] #MaxValue OUTPUT
GO

unqiueidenfitier is not compatible with type int SQL Server Procedure

I have the following procedure for inserting into a user table:
-- ================================================
-- Template generated from Template Explorer using:
-- Create Procedure (New Menu).SQL
--
-- Use the Specify Values for Template Parameters
-- command (Ctrl-Shift-M) to fill in the parameter
-- values below.
--
-- This block of comments will not be included in
-- the definition of the procedure.
-- ================================================
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: Andy Armstrong
-- Create date:
-- Description:
-- =============================================
CREATE PROCEDURE db_SignupAddLogin
-- Add the parameters for the stored procedure here
#LoginName VARCHAR(15),
#LoginPassword VARCHAR(15)
AS
BEGIN
DECLARE #GUID UNIQUEIDENTIFIER
SET #GUID = NEWID();
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for procedure here
INSERT INTO tblMemberLogin
(
UserID,
LoginName,
LoginPassword
)
VALUES
(
#GUID,
#LoginName,
#LoginPassword
)
RETURN #GUID
END
GO
However when I execute it I get the following error:
Msg 206, Level 16, State 2, Procedure db_SignupAddLogin, Line 34
Operand type clash: uniqueidentifier is incompatible with int
I cannot quite workout why as i am not referencing an int anywhere.
My Schema for tblMemberLogin looks like this:
UserID(PK,uniqueidentifier,notnull)
LoginName(nchar(15),not null)
LoginPassword(nchar(15),not null)
Please help!
RETURN can only be used with an int. You can simply use a SELECT query to retrieve the value of variable #GUID.
Reference: http://technet.microsoft.com/en-us/library/ms174998(v=sql.110).aspx
get rid of RETURN #GUID and you should be good to go.
In SQL Server, stored procedures may only return integer values. SQL Server RETURN
If you want to return data from a stored procedure other than an integer, you can use an output parameter: Returning Data from Stored Procedures
You declare the output parameter along with your input parameters:
CREATE PROCEDURE CREATE PROCEDURE db_SignupAddLogin
-- Add the parameters for the stored procedure here
#LoginName VARCHAR(15),
#LoginPassword VARCHAR(15),
#NewGuid UNIQUEIDENTIFIER OUTPUT
AS
BEGIN
SET #NewGuid = NEWID();
-- rest of procedure
END
And then use the output parameter:
DECLARE #NewLoginGuidFromSP UNIQUEIDENTIFIER
EXECUTE db_SignupAddLogin 'Username', 'password', #NewGuid = #NewLoginGuidFromSP OUTPUT;

int is incompatible with uniqueidentifier when no int usage

I am getting this error when there is absolutely no usage of int anywhere.
I have this stored procedure
ALTER procedure [dbo].[usp_GetFileGuid] #fileType varchar(25)
as
select [id] from fileTypes where dirId = #fileType
Here id is a uniqueidentifier in fileTypes table
When I execute the following
declare #fileGuid uniqueidentifier
exec #fileGuid = usp_GetFileGuid 'accounts'
print #fileGuid
I get the following error
(1 row(s) affected)
Msg 206, Level 16, State 2, Procedure usp_GetFileGuid, Line 0
Operand type clash: int is incompatible with uniqueidentifier
Is there anything wrong with the syntax of assigning output of stored procedure to the local variable? Thank you.
You are using EXEC #fileGuid = procedure syntax which is used for retrieving return values, not resultsets. Return values are restricted to INT and should only be used to return status / error codes, not data.
What you want to do is use an OUTPUT parameter:
ALTER procedure [dbo].[usp_GetFileGuid]
#fileType varchar(25),
#id UNIQUEIDENTIFIER OUTPUT
AS
BEGIN
SET NOCOUNT ON;
SELECT #id = [id] from dbo.fileTypes where dirId = #fileType;
-- if the procedure *also* needs to return this as a resultset:
SELECT [id] = #id;
END
GO
Then for usage:
declare #fileGuid uniqueidentifier;
exec dbo.usp_GetFileGuid #fileType = 'accounts', #id = #fileGuid OUTPUT;
print #fileGuid;
create procedure [dbo].[usp_GetFileGuid] #fileType varchar(25),#uuid uniqueidentifier output
as
select #uuid=[id] from fileTypes where dirId = #fileType
declare #fileGuid uniqueidentifier
exec usp_GetFileGuid 'accounts',#fileGuid output
print #fileGuid
The value returned is an int as it is the status of the execution
From CREATE PROCEDURE (Transact-SQL)
Return a status value to a calling procedure or batch to indicate
success or failure (and the reason for failure).
You are looking for an output parameter.
OUT | OUTPUT
Indicates that the parameter is an output parameter. Use
OUTPUT parameters to return values to the caller of the procedure.
text, ntext, and image parameters cannot be used as OUTPUT parameters,
unless the procedure is a CLR procedure. An output parameter can be a
cursor placeholder, unless the procedure is a CLR procedure. A
table-value data type cannot be specified as an OUTPUT parameter of a
procedure.

How Can i Let Stored Procedure Returns Varchar Value?

Here is my sample:
ALTER PROCEDURE EmpFirstName
#myParam int,
#empFName varchar(20) output
AS
BEGIN
SET NOCOUNT ON;
SELECT #empFName = empfname
FROM FE_QEMP
WHERE empno = #myParam
END
GO
myParam is the input and empFName will carry the output, so the procedure
should only take 1 parameter since empFName is the output, but in my case
i get this error:
Msg 201, Level 16, State 4, Procedure
EmpFirstName, Line 0 Procedure or
function 'EmpFirstName' expects
parameter '#empFName', which was not
supplied.
This is the way i called the procedure:
DECLARE #returnValue varchar(20)
EXEC #returnValue = EmpFirstName 10
SELECT 'Return Value ' = #returnValue
Return values and output parameters are two different things. If you want to call it with an output parameter, you'd do it like this:
EXEC EmpFirstName 10, #returnValue OUTPUT
SELECT 'Return Value ' + #returnValue
If you want to call it in the manner that you described in your example, then you need to alter the stored procedure to state RETURNS VARCHAR(20) and remove the output parameter. To return a value, you have to explicitly call return. In your example, you'd declare a variable, assign it in the select statement, then call return #varName.
Thanks. My aha moment came with this post. Did not realise that output parameters need to be qualified with the "output" identifier too when executed, not just in the procedure!
Here are my test workings for my fellow sql server noobs. I am using sqlcmd with sql server 2005.
The stored procedure:
/* :r procTest.sql */
if exists (select name from sysobjects where name="procTest" and type="P")
drop procedure procTest;
go
create procedure procTest
/* Test stored procedure elements. */
(#i_pt_varchar varchar(20),
#o_pt_varchar varchar(20) output)
as
begin
print "procTest";
set #o_pt_varchar = "string coming out";
print "#i_pt_varchar " + #i_pt_varchar;
print "#o_pt_varchar " + #o_pt_varchar;
return (0);
end
go
The test call:
/* :r procTest.test.sql */
declare #returnFlag int;
declare #i_varchar varchar(20);
declare #o_varchar varchar(20);
set #i_varchar = "string going in";
set #o_varchar = null;
execute #returnFlag = procTest #i_varchar, #o_varchar output
print "#returnFlag " + cast(#returnFlag as varchar(20));
print "after call";
print "#i_varchar " + #i_varchar;
print "#o_varchar " + #o_varchar;
go