How to make an output parameter in Stored Procedure in my scenario? - sql

I have a query, that will insert a data into my table, and it should return one value
My Stored Procedure
ALTER PROC FspCreateRequest
#RequestDescription nvarchar(200),
#CreatedBy varchar(30),
#CreatedDate datetime,
#Region nchar(10),
#RequestID varchar(20) output
AS
BEGIN
DECLARE #maxRequestID AS varchar(20)
SELECT #maxRequestID=max(RequestID)
FROM [F_CheckRequest]
WHERE Region = #Region
IF (#maxRequestID IS Null or #maxRequestID = '')
BEGIN
IF(#Region = 'Jeddah')
BEGIN
INSERT INTO [F_CheckRequest
(RequestID,RequestDescription,CreateBy,CreatedDate,Region)
VALUES
('10001',#RequestDescription,#CreatedBy,#CreatedDate,#Region)
SELECT #RequestID = '10001'
END
ELSE
BEGIN
INSERT INTO [F_CheckRequest]
(RequestID,RequestDescription,CreateBy,CreatedDate,Region)
VALUES
('50001',#RequestDescription,#CreatedBy,#CreatedDate,#Region)
SELECT #RequestID = '50001'
END
END
ELSE
BEGIN
SET #maxRequestID=#maxRequestID+1;
INSERT INTO [F_CheckRequest]
(RequestID,RequestDescription,CreateBy,CreatedDate,Region)
VALUES
(#maxRequestID,#RequestDescription,#CreatedBy,#CreatedDate,#Region)
SELECT #RequestID = #maxRequestID
END
END
When I run this query by following code
EXECUTE FspCreateRequest #RequestDescription='descriotion',#CreatedBy='sa',#CreatedDate='2017-01-10',#Region='Mecca',#ReqID out
PRINT 'RequestID'+ #ReqID
It throws error
Msg 137, Level 15, State 2, Line 2 Must declare the scalar variable "#ReqID".
Msg 137, Level 15, State 2, Line 3 Must declare the scalar variable "#ReqID".
Updated
Yes I did mistake. I missed to declare the output parameter. But after I execute like below
DECLARE #ReqID varchar(30)
EXECUTE FspCreateRequest #RequestDescription='descriotion',#CreatedBy='sa',#CreatedDate='2017-01-10',#Region='Jeddah',#ReqID out
PRINT 'RequestID'+ #ReqID
Still throws error like below
Msg 119, Level 15, State 1, Line 3
Must pass parameter number 5 and subsequent parameters as '#name = value'. After the form '#name = value' has been used, all subsequent parameters must be passed in the form '#name = value'.

This is the correct answer
DECLARE #ReqID varchar(30);
EXEC FspCreateRequest #RequestDescription='descriotion',#CreatedBy='sa',#CreatedDate='2017-01-10',#Region='Mecca',#RequestID = #ReqID out;
PRINT 'RequestID'+ #ReqID ;
Thank you #DanGuzman

Related

Msg 137, Level 15, State 2, Server ip-172-31-36-11, Line 2 Must declare the scalar variable "#Deptno"

My stored procedure (below) gives the following error:
Msg 137, Level 15, State 2, Server ip-172-31-36-11, Line 2 Must declare the scalar variable "#Deptno"
CREATE PROCEDURE EmployeesDept
#Deptno char(3)
AS
SELECT lastname AS Name
FROM Employee
WHERE workdept = #Deptno
GO
EXECUTE EmployeesDept #Deptno
GO
When it comes to executing a stored procedure you have to give the parameters values if you want it to work, and you can execute positionally or by name. You can put values in directly, or you can store values in variables and use those variables to give values to the stores procedure
--direct values
execute EmployeesDept 'abc', 0 --positional
execute EmployeesDept #Deptno='abc', #whatever=0 --named parameters
--values from variables
DECLARE #n CHAR(3) = 'abc';
DECLARE #i INT = 0;
execute EmployeesDept #n, #i --position based
execute EmployeesDept #Deptno = #n, #whatever = #i --name based
Named based parameters do not have to be in order, positional ones do
A better habit (for reasons of taking your skills to another DB) for CREATE PROCEDURE is like:
CREATE PROCEDURE EmployeesDept (
#Deptno char(3)
) AS
with parentheses around the argument list. For 2 or more args, separate with a comma. Example:
CREATE PROCEDURE EmployeesDept (
#Deptno char(3),
#whatever INT
) AS
Also get into the habit of ending each statement in a stored procedure with a semicolon

Run a procedure that uses already defined function in SQL as a boolean

So my issue is that I need the get_behorighet to be run withing the procedure do_uttag. I have checked that get_behorighet returns an int, either 1 or 0. But it does not seem to work however i change the syntax in my procedure.
The program returns an error when running the function do_uttag. Foreign keys and other table data seems not to be the issue here.
Msg 50000, Level 16, State 1, Procedure aifer_uttag, Line 10 [Batch Start Line 0]
Incorrect action
Msg 3609, Level 16, State 1, Procedure dbo.do_uttag, Line 11 [Batch Start Line 0]
The transaction ended in the trigger. The batch has been aborted
This is the main procedure
CREATE OR ALTER PROCEDURE do_uttag(
#p_radnr int,
#p_pnr varchar(11),
#p_knr int,
#p_belopp numeric(10,2),
#p_datum date)
AS
BEGIN
DECLARE #undantag int;
SET #undantag = (SELECT dbo.get_behorighet(#p_pnr, #p_knr));
PRINT cast(#undantag AS int)
IF #undantag = 1
BEGIN
INSERT INTO uttag (radnr, pnr, knr, belopp, datum)
VALUES (#p_radnr, #p_pnr, #p_knr, #p_belopp, #p_datum);
UPDATE konto
SET saldo = (saldo - #p_belopp)
WHERE knr = #p_knr;
declare #saldo numeric(10,2) = (select saldo from konto where knr = #p_knr);
PRINT 'Totalt saldo efter uttag: ' + CAST(#saldo AS VARCHAR(20));
END
ELSE
BEGIN
PRINT 'Uttag misslyckades';
END
END
This is the function that return 1 or 0
CREATE OR ALTER FUNCTION get_behorighet(
#p_pnr varchar(11),
#p_knr int)
RETURNS INT
AS
BEGIN
DECLARE #konto_value INT
/* uttag */
IF EXISTS (SELECT k.knr, ka.pnr FROM konto k, kontoagare ka WHERE (k.knr = #p_knr) AND (ka.pnr = #p_pnr))
BEGIN
SET #konto_value = 1
END
ELSE
BEGIN
SET #konto_value = 0
END
RETURN #konto_value
END
GO
For easier understanding of the problem that I am facing I have added an image of the database design.

Operand type clash: NULL is incompatible with SmallIntTable SQL Server

I'm trying to execute a simple stored procedure in SQL Server.
USE [dbname]
GO
DECLARE #return_value int
EXEC #return_value = [dbo].[usp_storprocname]
#ID = NULL,
#SomeID = 123456,
#AddressTypeIDs = NULL
SELECT 'Return Value' = #return_value
GO
What I'm getting is an error:
Msg 206, Level 16, State 2, Procedure usp_storprocname, Line 0 [Batch Start Line 2]
Operand type clash: NULL is incompatible with SmallIntTable
From what I understand, it expects to get some kind of an array with numbers in #AddressTypeIDs parameter. I don't need to filter results by that field. How can I pass a correct value there?
Before you execute the stored proc, Declare a variable of type SmallIntTable.
This will be a table with a single column, as you have learned.
Insert whatever values you wish into that table, and then when you Execute the stored procedure, pass that variable as the value for the #AddressTypeIDs parameter.
e.g. as below
USE [dbname]
GO
DECLARE #return_value INT
DECLARE #AddressTypeIDs dbo.SMALLINTCOL;
INSERT INTO #AddressTypeIDs
VALUES (1);
EXEC #return_value = [dbo].[usp_storprocname]
#ID = NULL,
#SomeID = 123456,
#AddressTypeIDs = #AddressTypeIDs
SELECT 'Return Value' = #return_value

SQL - If Parameters within Stored Procedure

I am trying to get a complex stored procedure to work, but I can't figure out the relationship between stored procedures, parameters and IF/THEN statements.
I have stripped my code down to the attached chunk of code, that shows where I am going wrong. When I execute it, I get an error
Msg 156, Level 15, State 1, Line 1
Incorrect syntax near the keyword 'and'
Basically, I have 3 variables - #Test1, #Test2 and #Test3. These are prompts that appear when you execute the stored procedure. If the user enters '1', '2', '3' respectively, it should show the text 'Show 1 and 2 and 3 Plus Pivot Section'. If the only enter '1','2' it should show the text 'Show 1 and 2 Plus Pivot Section'.
Below is my code, am I doing something wrong??
ALTER PROCEDURE [dbo].[sp_Data_Extract_Test]
#Test1 [NVARCHAR] (400),
#Test2 [NVARCHAR] (400),
#Test3 [NVARCHAR] (400)
WITH EXECUTE AS CALLER
AS
BEGIN
SET NOCOUNT ON;
DECLARE #Output NVARCHAR(400) ;
Declare #param NVARCHAR(900) ;
Set #param = '#Test1 nvarchar(400), #Test2 nvarchar(400), #Test3 nvarchar(400)'
if (#Test1 = '1')
BEGIN
SET #Output = 'Show 1';
END
if (#Test2 = '2')
BEGIN
SET #Output = #Output + ' and 2';
END
if (#Test3 = '3')
BEGIN
SET #Output = #Output + ' and 3';
END
BEGIN
SET #Output = #Output + ' Plus Pivot Section'
PRINT #Output
END
EXECUTE SP_EXECUTESQL #Output, #param, #Test1, #Test2, #Test3;
END
Edit: My example above isn't a good example. I was trying to narrow it down to identify the problem, but it seems as though the Execute statement at the bottom expects a SQL statement, not a line of text.
What I am trying to do, is effectively the following. I want to execute a stored procedure that pivot's a data set. The data is built up by 2 appends (unions) that are based on prompts. I want it so that the user can potentially run it for 1 type of Quantity, for 2, or for 3. If they want to see all 3 Quantities, it needs to do 2 appends. The code is as below. I've added XXX's where the SQL statement is because I know those parts are working fine, it's only when I try to do this if statement based on variables so I can potentially filter off the unions.
--- Above: Alter Stored Procedure, with variable declarations
declare #V1 NVARCHAR(4000) ;
declare #param NVARCHAR(900) ;
set #param='XXXXXX'
if (#Value1 = 'Qty_Ordered')
BEGIN
set #V1='SELECT XXXXXX’
END
if (#Value1 = 'Qty_Ordered' and #Value2 = 'Qty_Supplied')
BEGIN set #V1= #V1 + '
UNION ALL
SELECT XXXXX'
END
if ((#Value1 = 'Qty_Ordered' or #Value2 = 'Qty_Supplied') and #Value3 = 'Qty_Forecast')
BEGIN set #V1= #V1 +
'UNION ALL
SELECT XXXXXX’
END
BEGIN
set #V1 = #V1 + '
PIVOT
(
SUM([Value])
FOR p.forecast_Week_No IN ('+#cols1+','+#cols2+','+#cols3+')) AS pvt'
END
EXECUTE SP_EXECUTESQL #V1, #param, XXXXXXXX;
END
The frist paramenter for sp_executesql should be a TSQL statement, but #Output does not represent that.
If your intention was only to print the message then comment EXECUTE
SP_EXECUTESQL #Output, #param, #Test1, #Test2, #Test3;
Now regarding Msg 156, Level 15, State 1, Line 1 Incorrect syntax near the keyword 'and'
sqlserver basically checked for syntax error in the TSQL stmt passed through #Output,
what it got was "Show 1 and 2 and 3 Plus Pivot Section"
As SHOW is not a SQL stmt, it considered it as a stored proc,
next it looked at 1, and 1 it is allowed as a paramenter
next it got "and", it is not accepted to used words like "and" while executing a SP
so gave a syntax error Msg 156, Level 15, State 1...

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