29

我正在开发一个框架,其中我是一个带有动态创建参数的调用存储过程。我正在运行时构建参数集合。

当我将参数传递给存储过程时会出现问题,但存储过程不接受这样的参数。

例如,我的存储过程是:

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 实现吗?任何帮助,非常感谢。谢谢

4

5 回答 5

42

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
于 2013-03-03T22:24:53.660 回答
7

为什么要将参数传递给不使用它的存储过程?

在我看来,您可能会更好地构建动态 SQL 语句然后执行它们。你试图用 SP 做什么是行不通的,即使你可以改变你正在做的事情以适应不同数量的参数,那么你基本上是在使用动态生成的 SQL,你违背了首先拥有/使用SP。SP 有作用,但并非在所有情况下都有解决方案。

于 2013-03-03T22:18:08.913 回答
3

I'm going on a bit of an assumption here, but I'm assuming the logic inside the procedure gets split up via task. And you cant have nullable parameters as @Yuck suggested because of the dynamics of the parameters?

So going by my assumption

If TaskName = "Path1" Then Something

If TaskName = "Path2" Then Something Else

My initial thought is, if you have separate functions with business-logic you need to create, and you can determine that you have say 5-10 different scenarios, rather write individual stored procedures as needed, instead of trying one huge one solution fits all approach. Might get a bit messy to maintain.

But if you must...

Why not try dynamic SQL, as suggested by @E.J Brennan (Forgive me, i haven't touched SQL in a while so my syntax might be rusty) That being said i don't know if its the best approach, but could this could possibly meet your needs?

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

(The CHAR(13) adds a new line.. an old habbit i picked up somewhere, used to help debugging/reading dynamic procedures when running SQL profiler.)

于 2013-03-03T22:33:27.777 回答
3
CREATE PROCEDURE GetTaskEvents
@TaskName varchar(50),
@Id INT
AS
BEGIN
-- SP Logic
END

Procedure Calling

DECLARE @return_value nvarchar(50)

EXEC  @return_value = GetTaskEvents
        @TaskName = 'TaskName',
        @Id =2  

SELECT  'Return Value' = @return_value
于 2014-07-17T09:06:41.077 回答
0

You are parsing wrong parameter combination.here you passing @TaskName = and @ID instead of @TaskName = .SP need only one parameter.

于 2016-07-27T08:18:12.543 回答