我正在开发一个框架,其中我是一个带有动态创建参数的调用存储过程。我正在运行时构建参数集合。
当我将参数传递给存储过程时,会出现问题,但存储过程不接受此类参数。
比如我的存储过程是:
CREATE PROCEDURE GetTaskEvents
@TaskName varchar(50)
AS
BEGIN
-- SP Logic
END
调用存储过程为:
EXEC GetTaskEvents @TaskName = 'TESTTASK', @ID = 2
这会引发以下错误:
Msg 8144, Level 16, State 2, Procedure GetTaskEvents, Line 0
Procedure or function GetTaskEvents has too many arguments specified.
这在 Sybase ASE 中运行良好,它会忽略任何附加参数。 MSSQL Server 2008 可以实现这一点吗?任何帮助,非常感谢。谢谢
SQL Server 不允许您将参数传递给尚未定义的过程。我认为最接近这种设计的是使用可选参数,如下所示:
CREATE PROCEDURE GetTaskEvents
@TaskName varchar(50),
@ID int = NULL
AS
BEGIN
-- SP Logic
END;
您需要在定义中包含您可能使用的每个可能的参数。然后你就可以自由地以任何一种方式调用该过程:
EXEC GetTaskEvents @TaskName = 'TESTTASK', @ID = 2;
EXEC GetTaskEvents @TaskName = 'TESTTASK'; -- @ID gets NULL here
为什么要将参数传递给不使用该参数的存储过程?
在我看来,构建动态 SQL 语句然后执行它们可能会更好。你试图用SP做的事情是行不通的,即使你可以改变你正在做的事情以适应不同数量的参数,你本质上会使用动态生成的SQL,你就违背了目的首先拥有/使用 SP。 SP 有一定的作用,但并不是所有情况下都有解决方案。
我在这里进行一些假设,但我假设过程内部的逻辑通过任务进行分割。由于参数的动态性,您不能像 @Yuck 建议的那样拥有可为空的参数?
所以按照我的假设
如果任务名称 =“Path1”则某事
如果任务名称=“Path2”则其他
我最初的想法是,如果您需要创建具有业务逻辑的单独功能,并且您可以确定您有 5-10 个不同的场景,则可以根据需要编写单独的存储过程,而不是尝试一个庞大的解决方案所有方法。维护起来可能会有点混乱。
但是如果你必须...
为什么不尝试动态 SQL,正如 @E.J Brennan 所建议的那样(请原谅我,我有一段时间没有接触 SQL,所以我的语法可能生疏了)话虽如此,我不知道这是否是最好的方法,但是这能满足您的需求吗?
CREATE PROCEDURE GetTaskEvents
@TaskName varchar(50)
@Values varchar(200)
AS
BEGIN
DECLARE @SQL VARCHAR(MAX)
IF @TaskName = 'Something'
BEGIN
@SQL = 'INSERT INTO.....' + CHAR(13)
@SQL += @Values + CHAR(13)
END
IF @TaskName = 'Something Else'
BEGIN
@SQL = 'DELETE SOMETHING WHERE' + CHAR(13)
@SQL += @Values + CHAR(13)
END
PRINT(@SQL)
EXEC(@SQL)
END
(CHAR(13)添加了一个新行..我在某处学到的一个老习惯,用于帮助调试/读取动态过程 运行 SQL 探查器时。)
CREATE PROCEDURE GetTaskEvents
@TaskName varchar(50),
@Id INT
AS
BEGIN
-- SP Logic
END
过程调用
DECLARE @return_value nvarchar(50)
EXEC @return_value = GetTaskEvents
@TaskName = 'TaskName',
@Id =2
SELECT 'Return Value' = @return_value
您正在解析错误的参数组合。这里您传递的是
@TaskName =
和 @ID
而不是 @TaskName =
。SP 只需要一个参数。
创建过程 GetTaskEvents @TaskName varchar(50) @Values varchar(200) 作为 开始 声明@SQL VARCHAR(MAX)
IF @TaskName = '某事' 开始 @SQL = '插入......' + CHAR(13) @SQL += @Values + CHAR(13) 结束
IF @TaskName = '其他' 开始 @SQL = '删除某处的内容' + CHAR(13) @SQL += @Values + CHAR(13) 结束
打印(@SQL)
执行(@SQL)
结束