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

发布于 2024-11-08 00:17:02 字数 1612 浏览 0 评论 0原文

我在动态 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

我收到以下错误。

消息 245,级别 16,状态 1,Procedurecagroup,第 33 行 转换 nvarchar 值 'SELECT [Gro] AS GName 时转换失败, ' 转换为 int 数据类型。

我哪里做错了?

I have created a procedure in dynamic SQL which has a select statement and the code looks like:

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

When I am executing this procedure with this statement:

Exec  dbo.cagroup  1,10,'[Gro]',1,1,NULL

I am getting the following error.

Msg 245, Level 16, State 1, Procedurecagroup, Line 33
Conversion failed when converting the nvarchar value 'SELECT [Gro] AS GName ,
' to data type int.

Where am I doing wrong?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

ヅ她的身影、若隐若现 2024-11-15 00:17:02

您需要将连接中的所有数字转换为 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 有一个很好的观点:注意 NULL!

You need to CAST all numbers to nvarchar in the concatenation.

There is no implicit VBA style conversion to string. In SQL Server data type precedence means ints are higher then nvarchar: so the whole string is trying to be CAST to int.

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

Edit: Will A has a good point: watch for NULLs!

梅窗月明清似水 2024-11-15 00:17:02

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

Select * from Information_Schema.Columns Where Table_name=@TableName

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

If you have to build this kind of dynamic SQL, it is better to get the column information from the meta-data than to pass it around.

Select * from Information_Schema.Columns Where Table_name=@TableName

The you have to write an ugly cursor to build the SQL. Expect performance problems. I do lots of this during development to write code for me, but I don't dare run it in production.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文