I want to be able to pass in the name of a stored procedure as a string into another stored procedure and have it called with dynamic parameters. I'm getting an error though.
Specifically I've tried:
create procedure test #var1 varchar(255), #var2 varchar(255) as
select 1
create procedure call_it #proc_name varchar(255)
as
declare #sp_str varchar(255)
set #sp_str = #proc_name + ' ''a'',''b'''
print #sp_str
exec #sp_str
exec call_it 'test'
So procedure call_it should call procedure test with arguments 'a', and 'b'.
When I run the above code I get:
Msg 2812, Level 16, State 62, Procedure call_it, Line 6
Could not find stored procedure 'test 'a','b''.
However, running test 'a','b' works fine.
you need parentheses
exec (#sp_str)
if the proc didn't exists the message would be this
Msg 2812, Level 16, State 62, Line 1
Could not find stored procedure 'test'.
it would not be Could not find stored procedure 'test 'a','b''
Although still a bad idea with SQL injection, try using sp_executeSQL and use parameters, see here about query plan reuse: Changing exec to sp_executesql doesn't provide any benefit if you are not using parameters correctly
You should use the "sp_executesql" procedure. Look at MSDN - sp_executesql.
You don't need any kind of dynamic SQL (EXEC() or sp_executesql) at all to achieve this result:
create procedure test #var1 varchar(255), #var2 varchar(255)
as
BEGIN
select #var1, #var2;
END;
create procedure call_it #proc_name varchar(255)
as
BEGIN
declare #param1 VARCHAR(255) = 'a'
,#param2 VARCHAR(255) = 'b';
exec #proc_name #param1, #param2; --it isn't dynamic-SQL(simple procedure call)
END;
exec call_it #proc_name = 'test';
DBFiddle Demo
From EXECUTE:
[ { EXEC | EXECUTE } ]
{
[ #return_status = ]
{ module_name [ ;number ] | #module_name_var }
#module_name_var
Is the name of a locally defined variable that represents a module name.
This can be a variable that holds the name of a natively compiled, scalar user-defined function.
Related
I'm trying to EXEC a stored procedure inside an nvarchar that I a them executing.
I receive the following error, Msg 2812, Level 16, State 62, Procedure Map.AdminServiceLoad, Line 127 [Batch Start Line 2]
Could not find stored procedure ''.
The stored procedures I am referencing exist, I had re-started MSSQL, am I unable to EXEC with an EXEC ?
DECLARE #NewStoredProc nvarchar(max) = '
create procedure [Map].[Load'+#TableName+']
as
begin
DECLARE #MapTable nvarchar(100) = [Map].['+#TableName+']
DECALRE #MapDevlTable nvarchar(100) = [MapDevl].['+#TableName+']
DECLARE #ShapesAreValid bit
DECLARE #PointsAreValid bit
EXEC #ShapesAreValid = Map.AdminServiceValidateShapes #TableName = #MapDevlTable
EXEC #PointsAreValid = Map.AdminServiceValidatePoints #TableName = #MapDevlTable
if(#ShapesAreValid = 1 and #PointsAreValid = 1)
begin
INSERT INTO [Map].['+#TableName+'] SELECT('+#ColsToLoad+') FROM [MapDevl].['+#TableName+']
end
end
'
EXEC #NewStoredProc
return 1
It would need to be EXEC(#cmd) not EXEC #cmd.
Without the parentheses it looks to find a stored procedure with the same name as the string inside #cmd.
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.
if(filename==x)
exec stored procedure1
else if (filename==y)
exec stored procedure2
else
exec stored procedure3
filename is stored in a table .
How to do this in sql server?
Is there a part you're having trouble with? This is how you would get the file name from a table:
Declare #filename nvarchar(100)
Select #filename = filename_column from tablename
The syntax for if statements is
If #filename='xxx'
Begin
...
End
Executing a stored procedure is done with exec, just like in your pseudo code.
I have a stored procedure say #Create_Dummy1 which is being passed a variable. This is declared as #Dummy_Variable1 in this stored procedure.
Next I need to call another stored procedure #Create_Dummy2 from #Create_Dummy1. I need to pass #Dummy_Variable1 in the exec statement.
But if I try to do this the string #Dummy_Variable1 is only being passed instead of the value it holds.
I'm executing procedures inside other procedures like this:
DECLARE #childResult int, #loaErrorCode int, #loaErrorMessage varchar(255)
EXEC #childResult = [dbo].[proc_sub_getSomething] #schemes_id = #foo_schemes_i, #errorCode = #loaErrorCode OUTPUT , #errorMessage = #loaErrorMessage OUTPUT
Should it still not work you should edit your question to show your exact code.
This should work:
create procedure Create_Dummy1
(
#Dummy_Variable1 int
)
as
exec Create_Dummy2 #Dummy_Variable1
Go
And
create procedure Create_Dummy2
(
#Dummy_Variable1 int
)
as
Select * From yourTable WHERE tableColumn = #Dummy_Variable1
And this is how you call it:
exec Create_Dummy1 1
Hope this helps.
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