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

2021-12-02 00:00:00 sql sql-server-2005 casting tsql sql-server

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

I am trying to write a stored procedure to assist with development of our database, but I am having some trouble using it. For example:

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

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

This yields the error (on SQL Server 2005):

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

Msg 102, Level 15, State 1, Line 4 Incorrect syntax near '+'.

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

Can someone explain to me why my syntax is incorrect, and the right way to solve this problem?

推荐答案

你需要使用一个中间变量.SQL Server虽然已经在TODO列表上好几年了,但它本身并不支持参数列表中的这种操作!(参见 连接项目:使用标量函数作为存储过程参数)

You need to use an intermediate variable. SQL Server does not support this kind of operation in the parameter list itself though it has been on the TODO list for a few years! (See Connect Item: Use scalar functions as stored procedure parameters)

EXEC 的语法是

[ { EXEC | EXECUTE } ]
    { 
      [ @return_status = ]
      { module_name [ ;number ] | @module_name_var } 
        [ [ @parameter = ] { value 
                           | @variable [ OUTPUT ] 
                           | [ DEFAULT ] 
                           }
        ]
      [ ,...n ]
      [ WITH <execute_option> [ ,...n ] ]
    }
[;]

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

The documentation is not currently that clear on an acceptable format for value but it seems to be only "simple" expressions such as literal values or @@ prefixed system functions (such as @@IDENTITY). Other system functions such as SCOPE_IDENTITY() are not permitted (even those which do not require parentheses such as CURRENT_TIMESTAMP are not allowed).

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

So for the time being you need to use syntax such as the below

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 

相关文章