【问题标题】:Dynamic SQL error converting nvarchar to int将 nvarchar 转换为 int 的动态 SQL 错误
【发布时间】:2011-08-27 10:14:17
【问题描述】:

我在动态 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,Procedurecagroup,第 33 行 转换 nvarchar 值 'SELECT [Gro] AS GName 时转换失败, ' 转换为 int 数据类型。

我哪里做错了?

【问题讨论】:

  • 该代码要么不起作用,要么已从工作代码中修改以使其无法工作。特别是,据我所知,@GName 没有被声明,无论如何,这段代码:AND' + @GName + 'IS NOT NULL 将不起作用,除非@GName 前后都有空格。
  • @Cade Roux 我编辑了那些只是错字的代码
  • 动态性需要什么?
  • @Dforck 表将根据@DataID 改变
  • @Sam,为什么不创建一个脚本来生成你的 crud 程序,然后执行这些程序呢?与动态创建的插入和选择相比,让代码生成的 sp 更容易维护。

标签: sql sql-server sql-server-2008 stored-procedures dynamic-sql


【解决方案1】:

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

没有隐式的 VBA 样式转换为字符串。在 SQL Server 数据类型优先级意味着 int 比 nvarchar 高:所以整个字符串都试图 CAST 到 int。

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

编辑:A 有一个很好的观点:注意 NULL!

【讨论】:

  • @GBN 非常感谢。我向所有数字添加了强制转换,当我执行它时,它只是说 Query Executed 成功它不会打印 sql 语句。有什么需要修改的吗
  • @Sam - 检查您在连接中使用的值是否为 NULL - 尝试连接 NULL,您最终会得到 NULL。
  • @Will A Ya,你是对的,我的值之一是串联中的 null。参数@Key 我将 null 传递给它我该如何处理?
  • @Sam - COALESCE(@mightbenull, 'string to use if value is null')
【解决方案2】:

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

Select * from Information_Schema.Columns Where Table_name=@TableName

你必须编写一个丑陋的游标来构建 SQL。预计性能问题。我在开发过程中做了很多这样的事情来为我编写代码,但我不敢在生产中运行它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-22
    • 2011-04-16
    • 2020-11-12
    • 1970-01-01
    • 2012-10-18
    相关资源
    最近更新 更多