How Can i Let Stored Procedure Returns Varchar Value? - sql

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

Related

The Formal Parameter #QueryComplete was not declared as output. What might be the problem. The entire stored procedure is attached. Thanks

I have built the following stored procedure. It seems to be working fine and the data is going into the table. However, the Programmable Logic Controller is not able to pick the #QueryComplete value to be 1. What might be the issue here. The only error warning is as follows:
The Formal Parameter #QueryComplete was not declared as output.
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[SP_Genealogy_WIP]
-- Add the parameters for the stored procedure here
#engine_number as nvarchar(50),
#line_id as int,
#stage_id as int,
#activity_id as int,
#activity_value as nvarchar(50),
#quantity as int,
#status as int,
#plc_YYYY as int,
#plc_MM as int,
#plc_DD as int,
#plc_HR as int,
#plc_MIN as int,
#plc_SEC as int,
-- [Sending Output]
#QueryComplete int OUTPUT
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from;
-- interfering with SELECT statements.
--SET NOCOUNT ON;
Declare #plc_timestamp nvarchar(20);
SET #plc_timestamp = cast(#plc_YYYY as nvarchar(4)) + '-' + Cast(#plc_MM as nvarchar(2)) + '-' + Cast(#plc_DD as nvarchar(2)) + ' ' + Cast(#plc_HR as nvarchar(2)) + ':' + Cast(#plc_MIN as nvarchar(2)) + ':' + Cast(#plc_SEC as nvarchar(2));
SELECT #plc_timestamp as 'PLC TIMESTAMP';
-- Building the Create Statement
BEGIN TRY
INSERT INTO [dbo].[Genealogy_WIP] (
[engine_number]
,[line_id]
,[stage_id]
,[activity_id]
,[activity_value]
,[quantity]
,[status]
,[plc_timestamp]
) VALUES (
#engine_number,
#line_id,
#stage_id,
#activity_id,
#activity_value,
#quantity,
#status,
CAST(#plc_timestamp as datetime)
);
SET #QueryComplete = 1;
SELECT #QueryComplete OUTPUT;
SELECT ' Inserted successfully.' AS Response;
END TRY
BEGIN CATCH
-- statement to handle errors
IF ERROR_NUMBER()=2627
SELECT '[Error]-You cannot insert this value into the table as there is a primary key violation (in the Line ID field) or one of the inputs is incorrect.' AS Response
END CATCH
END
When you have to OUTPUT a value from a parameter you must
specify the parameter with the keyword OUTPUT in the parameter list (you have done it)
set a value to any OUTPUT parameter with SET or SELECT and nothing else (your line "SELECT #QueryComplete OUTPUT;" is wrong. Just write SELECT #QueryComplete = ???" where ??? is a value;
To execute a procedure with a parameter in OUTPUT you must :
Declare a variabale that will accept the returned value
Write the exec command and specify OUTPUT for the returned value
Read the returned value
Example :
DDL :
CREATE PROC P #DT DATETIME2 OUTPUT
AS
SET #DT = SYSUTCDATETIME();
GO
EXEC :
DECLARE #DATETIME2_READ DATETIME2;
EXEC P #DATETIME2_READ OUTPUT;
SELECT #DATETIME2_READ;

Stored procedure returns 0 instead of value

There is a stored procedure that can return top 1 result as
USE [DB]
GO
.....
CREATE PROCEDURE [dbo].[GET]
(#in VARCHAR(10), #Out VARCHAR(10) OUTPUT)
AS
SELECT top 1 #Out = tab.Col
FROM table tab
RETURN
GO
When I call it in main query
DECLARE #output VARCHAR(10)
DECLARE #in VARCHAR(10)
DECLARE #Out VARCHAR(10)
EXECUTE dbo.GET #in = 'table', #Out = #output
It prints #output as 0;
but if I do
EXECUTE dbo.GET #in = 'table', #Out = #Out
And print #out, I get the correct value.
Why could this happen?
I did pass output #Out to pre-defined variable #output
Assuming SQLS due to presence of 'dbo' and sqlserver tag
Your query in the procedure doesn't assign a value to the out parameter (called #out) it assigns to some other variable called #outpk. Resolve the naming mismatch and make them the same
Sqlserver does not support LIMIT. To limit result set size use SELECT TOP 1 *. Using TOP (or any similar result set restrictor) without ORDER BY is illogical. Specify an ORDER BY
In sqlserver, output parameters must be passed with the OUTPUT keyword when calling the procedure:
EXEC sprocname #inputparameter ='value', #outputparameter = #variableToSet OUTPUT;
Use semicolons; omitting them is deprecated
Example
USE [DB]
GO
CREATE PROCEDURE [dbo].[GET]
(#in VARCHAR(10), #OutPk VARCHAR(10) OUTPUT)
AS
SELECT #OutPK = tab.Col
FROM table tab
ORDER BY tab.Col;
GO
DECLARE #output VARCHAR(10);
EXECUTE dbo.GET #in = 'table', #OutPK = #output OUTPUT
SELECT #output;
If its MySql (Limit is in mySql), you can simply call:
Call dbo.GET('table', #out);
No need to have separate variable #output.

Save result of stored procedure to variable

Given a stored procedure like the one shown below:
CREATE PROCEDURE [dbo].[GetBusinessUnitSysNameAndGroupNames]
#ModelAfter varchar(100),
#BusinessUnitSystemName varchar(100) OUT,
#GroupsName varchar(4000) OUT
AS
BEGIN
if (#ModelAfter = 'Corporate')
BEGIN
SET #GroupsName = 'Admins'
SET #BusinessUnitSystemName = 'AcmeOutdoors'
END
else if (#ModelAfter = 'Retailers')
BEGIN
SET #GroupsName = 'Sellers'
SET #BusinessUnitSystemName = 'AcmeShoppers'
END
END
When I run from the SQL Studio command line:
EXEC [dbo].[GetBusinessUnitSysNameAndGroupNames] '~ModelAfter~', 'acmeoutdoors', 'admins'
I just get a result in the message panel like Command(s) completed successfully. But what I would like to see the actual result, not just a success message. Something like shown below(which doesn't work, just my idea).
DECLARE #Result varchar(max)
SET #Result = EXEC [dbo].[GetBusinessUnitSysNameAndGroupNames] '~ModelAfter~', 'acmeoutdoors', 'admins'
PRINT #Result
Returning Data by Using OUTPUT Parameters
If you specify the OUTPUT keyword for a parameter in the procedure
definition, the stored procedure can return the current value of the
parameter to the calling program when the stored procedure exits. To
save the value of the parameter in a variable that can be used in the
calling program, the calling program must use the OUTPUT keyword when
executing the stored procedure.
DECLARE #Result1 varchar(max), #Result2, varchar(max)
EXEC [dbo].[GetBusinessUnitSysNameAndGroupNames] 'Corporate', #Result1 OUT, #Result2 OUT
PRINT #Result1
PRINT #Result2

user defined function call vs calling UDF in a Store procedure

I have a user defined function that is called inside a stored procedure. All that stored procedure does is return the value that is obtained from the UDF scalar function.
However,
Select * UDF_FunctionName(param1,param2)
udf call is here-
SELECT dbo.udfFunction('1234',10) as result
and
Exec StoreProcName(param1,param2)
are returning different results.
StoreProcName calls the `UDF_FunctionName(param1,param2)
sproc code is here-
BEGIN
SET NOCOUNT ON;
Return SELECT [DbName].[dbo].[udfFunction](#param1, #param2)
END
What could be the reason for different results?.
You are trying to use RETURN and SELECT together:
Return SELECT [DbName].[dbo].[udfFunction](#param1, #param2)
You cannot do that, you either want to return the result, or select it. Depending on which you choose, retrieving the value will differ.
If you do this:
SELECT [DbName].[dbo].[udfFunction](#param1, #param2)
Then the resultset will have a single row and column containing your value. Access this exactly as you would any other resultset.
If you do this:
RETURN [DbName].[dbo].[udfFunction](#param1, #param2)
Your stored procedure will have a return value which is the result of your function call. Access this by defining a scalar variable and assigning it to the result of the SP call - assuming the result is INT that might look like
DECLARE #result INT
EXEC #Result = StoredProcName(#param1, #param2)
You should not use RETURN in this way in a stored procedure. If you want to return a scalar value to the calling code use an OUTPUT parameter. RETURN is generally used for status codes.
You might have something like
-- SAMPLE UDF
CREATE FUNCTION dbo.YourUDF (#Username VARCHAR(30), #EntityID INT)
RETURNS INT
AS
BEGIN
RETURN #EntityID;
END
GO
-- SAMPLE PROCEDURE
CREATE PROCEDURE dbo.YourProc #Username VARCHAR(30), #EntityID INT, #Output INT OUTPUT
AS
BEGIN
SET NOCOUNT ON;
SET #Output = dbo.YourUDF(#Username, #EntityID);
IF #Output IS NULL -- AN ERROR
BEGIN
RETURN 1; -- RETURN A STATUS OF -1 TO INDICATE ERROR
END
END
Then you could call this as:
DECLARE #Output INT, #ReturnValue INT;
EXECUTE #ReturnValue = dbo.YourProc
#Username = '1234',
#EntityID = 1,
#Output = #Output OUTPUT;
SELECT ValueFromUDF = #Output,
ReturnValue = #ReturnValue;
This returns:
ValueFromUDF ReturnValue
------------------------------
1 0
If we pass NULL as #EntityID, to trigger the artificial error, then we get a return status of -1:
DECLARE #Output INT, #ReturnValue INT;
EXECUTE #ReturnValue = dbo.YourProc
#Username = '1234',
#EntityID = NULL,
#Output = #Output OUTPUT;
SELECT ValueFromUDF = #Output,
ReturnValue = #ReturnValue;
ValueFromUDF ReturnValue
------------------------------
NULL 1

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.