在存储过程参数列表中使用表达式的结果(例如函数调用)?

Wor*_*ead 16 sql t-sql sql-server casting sql-server-2005

我正在尝试编写一个存储过程来协助开发我们的数据库,但是我在使用它时遇到了一些麻烦.例如:

DECLARE @pID int;
SET @pID = 1;
EXEC WriteLog 'Component', 'Source', 'Could not find given id: ' + CAST(@pID AS varchar);
Run Code Online (Sandbox Code Playgroud)

这会产生错误(在SQL Server 2005上)

消息102,级别15,状态1,行4'+'附近的语法不正确.

有人可以向我解释为什么我的语法不正确,以及解决这个问题的正确方法吗?

Mar*_*ith 18

您需要使用中间变量.SQL Server不支持参数列表本身的这种操作,尽管它已经在TODO列表上存在了几年!(请参阅连接项:使用标量函数作为存储过程参数)

文法EXEC IS

[ { EXEC | EXECUTE } ]
    { 
      [ @return_status = ]
      { module_name [ ;number ] | @module_name_var } 
        [ [ @parameter = ] { value 
                           | @variable [ OUTPUT ] 
                           | [ DEFAULT ] 
                           }
        ]
      [ ,...n ]
      [ WITH <execute_option> [ ,...n ] ]
    }
[;]
Run Code Online (Sandbox Code Playgroud)

文档目前在可接受的格式上并不清楚,value但它似乎只是"简单"的表达式,如文字值或@@前缀系统函数(如@@IDENTITY).其他系统功能SCOPE_IDENTITY()是不允许的(即使那些不需要括号的系统功能CURRENT_TIMESTAMP也是不允许的).

所以暂时你需要使用如下的语法

DECLARE @pID INT;

SET @pID = 1;

/*If 2008+ for previous versions this needs to be two separate statements*/
DECLARE @string VARCHAR(50) = 'Could not find given id: ' + CAST(@pID AS VARCHAR(11))

EXEC WriteLog
  'Component',
  'Source',
  @string 
Run Code Online (Sandbox Code Playgroud)

  • 我希望避免中间变量.有没有正确的方法来做到这一点而不引入它们? (3认同)