将nvarchar转换为int时发生动态SQL错误

将nvarchar转换为int时发生动态SQL错误,sql,sql-server,sql-server-2008,stored-procedures,dynamic-sql,Sql,Sql Server,Sql Server 2008,Stored Procedures,Dynamic Sql,我在动态SQL中创建了一个过程,该过程有一个select语句,代码如下所示: ALTER PROCEDURE cagroup ( @DataID INT , @days INT , @GName VARCHAR(50) , @T_ID INT , @Act BIT , @Key VARBINARY(16) ) AS BEGIN DECLARE @SQL NVARCHAR(MAX) DECLARE @SchemaName SYS

我在动态SQL中创建了一个过程,该过程有一个select语句,代码如下所示:

ALTER PROCEDURE cagroup    (
    @DataID INT ,
    @days INT ,
    @GName VARCHAR(50) ,
    @T_ID INT ,
    @Act BIT ,
    @Key VARBINARY(16)
)
AS
BEGIN
    DECLARE @SQL NVARCHAR(MAX)
    DECLARE @SchemaName SYSNAME
    DECLARE @TableName SYSNAME
    DECLARE @DatabaseName SYSNAME
    DECLARE @BR CHAR(2)
    SET @BR = CHAR(13) + CHAR(10)

    SELECT  @SchemaName = Source_Schema ,
            @TableName = Source_Table ,
            @DatabaseName = Source_Database
    FROM    Source
    WHERE   ID = @DataID

SET @SQL =  'SELECT ' + @GName + ' AS GrName ,' + @BR
                + @T_ID + ' AS To_ID ,' + @BR
                + @DataID + ' AS DataSoID ,' + @BR
                + @Act + ' AS Active ,' + @BR
                + Key + ' AS key' + @BR
                + 'R_ID AS S_R_ID' + @BR
                + 'FROM' + @DatabaseName + '.'
                + @SchemaName + '.'
                + @TableName + ' t' + @BR
                + 'LEFT OUTER JOIN Gro g ON g.GName = '
                    + @GName + @BR + 'AND g.Data_ID] =' + @DataID + @BR
                    + 't.[I_DATE] > GETDATE() -' + @days + @BR
                    + 'g.GName IS NULL
                        AND ' + @GName + ' IS NOT NULL
                        AND t.[Act] = 1' + @BR

    PRINT (@SQL)
END
当我使用此语句执行此过程时:

Exec  dbo.cagroup  1,10,'[Gro]',1,1,NULL
我得到以下错误

Msg 245,16级,状态1,程序组,第33行 转换nvarchar值“选择[Gro]作为GName”时,转换失败, '到数据类型int


我哪里做错了?

您需要在串联中将所有数字强制转换为nvarchar

不存在到字符串的隐式VBA样式转换。在SQL Server中,数据类型优先级意味着int高于nvarchar:因此整个字符串都试图转换为int

SET @SQL =  'SELECT ' + @GName + ' AS GrName ,' + @BR
              + CAST(@T_ID AS nvarchar(10)) + ' AS To_ID ,' ...

编辑:Will A有一个很好的观点:注意空值

如果必须构建这种动态SQL,那么最好从元数据中获取列信息,而不是传递它

Select * from Information_Schema.Columns Where Table_name=@TableName

最后,您必须编写一个难看的游标来构建SQL。预期性能问题。我在开发过程中做了很多这样的事情来为自己编写代码,但我不敢在生产中运行它。

@GBN非常感谢您。我将cast添加到所有数字中,当我执行它时,只会说queryexecuted successfully,它不会打印sql语句。有什么需要我帮忙的吗modify@Sam-检查您在串联中使用的值是否为空-尝试串联一个空值,您将得到一个空值。@是的,您是对的,我的一个值在串联中为空值。参数@Key i正在向它传递空值。我如何处理它?@Sam-
COALESCE(@mightbenull,“值为null时使用的字符串”)
该代码要么不工作,要么是从工作代码中修改出来的,使其无法工作。特别是,据我所知,@GName没有被声明,而且在任何情况下,这段代码:“++@GName+”不为NULL将无法工作,除非@GName前后都有空格。@Cade Roux我编辑了代码,这些代码只是打字错误。这是什么需要动态性吗?@Dforck表将根据不同的@DataID@Sam,为什么不创建一个脚本来生成crud过程,然后执行这些过程呢?使用代码生成sp将比动态创建插入和选择更容易维护。