我希望能够将存储过程的名称作为字符串传递到另一个存储过程,并使用动态参数调用它。我虽然收到了错误。
特别是我试过了:
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'
因此,过程call_it应使用参数'a'和'b'调用过程测试。
当我运行上面的代码时,我得到:
Msg 2812,Level 16,State 62,Procedure call_it,Line 6 找不到存储过程'test'a','b''。
然而,运行测试'a','b'工作正常。
答案 0 :(得分:8)
你需要括号
exec (@sp_str)
如果proc不存在,则消息将为此
Ms 2812,Level 16,State 62,Line 1 找不到存储过程'test'。
它不会无法找到存储过程'test'a','b''
虽然使用SQL注入仍然是个坏主意,但请尝试使用sp_executeSQL并使用参数,请参阅此处有关查询计划重用的信息:Changing exec to sp_executesql doesn't provide any benefit if you are not using parameters correctly
答案 1 :(得分:3)
您应该使用“sp_executesql”过程。请看MSDN - sp_executesql。
答案 2 :(得分:0)
您根本不需要任何类型的动态SQL(EXEC()
或sp_executesql
)来实现此结果:
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 强>
来自EXECUTE:
[ { EXEC | EXECUTE } ] { [ @return_status = ] { module_name [ ;number ] | @module_name_var }
<强> @module_name_var 强>
是表示模块名称的本地定义变量的名称。
这可以是一个变量,它包含本机编译的标量用户定义函数的名称。