首页 > 解决方案 > 使用变量声明时出错 '+@TABLENAME1+' 附近的语法不正确

问题描述

DECLARE @SQLSTRING VARCHAR(1500);
 DECLARE @TABLENAME1 VARCHAR(30)='NOV19_COMBINE'
---------------TABLE CREATION WITH FILE NAME--------------------------
SET @SQLSTRING = 'SELECT
    CONVERT(VARCHAR('+ cast((select max(len(EMAIL)) from '+@TABLENAME1+' ) as VARCHAR(50))+'),  EMAIL   ) AS    EMAIL,
    IDENTITY (INT,1,1) AS RECORDID
            INTO FOI_'+@TABLENAME1+'_CONV
FROM '+@TABLENAME1+' A' 
    PRINT @SQLSTRING

错误:

消息 102,级别 15,状态 1,第 8 行
'+@TABLENAME1+' 附近的语法不正确。

标签: sql-server

解决方案


你在这里有一个问题:

CONVERT(VARCHAR('+ cast((select max(len(EMAIL)) from ' + @TABLENAME1 + ' ) as VARCHAR(50))+')

您试图从@TABLENAME1. 这也需要成为您的动态 SQL 的一部分。

但是,您的convert(varchar(代码还有另一个问题,即您不能将变量用作varchar(). 我建议使用varchar(max),因为它只使用所需的存储空间。

我还使您的动态 SQL 免受注入QUOTENAME,我建议您将来使用它。

固定版本:

DECLARE @SQLSTRING VARCHAR(1500);
DECLARE @TABLENAME1 VARCHAR(30) = 'NOV19_COMBINE'
---------------TABLE CREATION WITH FILE NAME--------------------------
SET @SQLSTRING = 'SELECT CONVERT(VARCHAR(max), EMAIL) AS EMAIL, IDENTITY (INT,1,1) AS RECORDID INTO '
  + QUOTENAME('FOI_' + @TABLENAME1 + '_CONV') + ' FROM '
  + QUOTENAME(@TABLENAME1) + ' A' 
PRINT @SQLSTRING

我没有理由想到这样做,但作为一项学术练习,如果真的需要EMAIL列的确切长度,那么可以使用以下查询:

declare @SQLSTRING nvarchar(max), @TABLENAME1 VARCHAR(30) = 'NOV19_COMBINE', @EMAILLENGTH int
SET @SQLSTRING = 'SELECT @Length = max(len(EMAIL)) from ' + QUOTENAME(@TABLENAME1)
EXECUTE sp_executesql @SQLSTRING, N'@Length int OUTPUT', @Length = @EMAILLENGTH OUTPUT
SET @SQLSTRING = 'SELECT CONVERT(VARCHAR(' + convert(varchar(4),@EMAILLENGTH) + '), EMAIL) AS EMAIL'
  + ', IDENTITY (INT,1,1) AS RECORDID'
  + ' INTO ' + QUOTENAME('FOI_' + @TABLENAME1 + '_CONV')
  + ' FROM ' + QUOTENAME(@TABLENAME1) + ' A' 
PRINT @SQLSTRING

这需要 2 段动态 SQL,第一个找到EMAIL列的长度,然后用于构建动态 SQL 以用于实际查询。


推荐阅读