【问题标题】:Not a valid Identifier T SQL Dynamic SQL inside a CTE不是有效的标识符 T SQL CTE 中的动态 SQL
【发布时间】:2017-09-27 19:56:52
【问题描述】:

处理将结果存储在临时表中并希望转换为 CTE 的存储过程。

代码:

DECLARE  @SQL nVARCHAR(max)

SET @SQL = '
;with CTE_RESULT 
(
        CAMP_ABBR,
        ORIG_CALL_DATE,
        DONOR_ID,
        ACCOUNT_NUMBER_100,
        COMPANY_NAME_100,
        FIRST_NAME,
        LAST_NAME,
        PHONE,
        STREET1,
        STREET2,
        STATE,
        CITY,
        ZIP_CODE,
        WAVE_NAME,
        EMAIL,
        ORIGINAL_EMAIL,
        CODE1,
        DISPOSITION_CODE,
        DESCRIPTION 
)AS

(
SELECT  CAMP_ABBR,
        CONVERT(VARCHAR,ORIG_CALL_DATE,101),
        DONOR_ID,
        ACCOUNT_NUMBER_100 AS ACCOUNT_ID,
        COMPANY_NAME_100,
        FIRST_NAME,
        LAST_NAME,
        TEL_AREA_CODE + TEL_PREFIX + TEL_ROOT AS PHONE,
        STREET1,
        STREET2,
        STATE,
        CITY,
        ZIP_CODE,
        WAVE_NAME,
        EMAIL,
        ORIGINAL_EMAIL,
        CODE1,
        R.DISPOSITION_CODE,
        D.DESCRIPTION 
FROM placeholder1 t1
WHERE COLUMN IN(''01'',''02''))
'

EXEC @SQL

返回以下错误:

消息 203,第 16 级,状态 2,第 114 行
名称 ' ;with CTE_RESULT (CAMP_ABBR, ORIG_CALL_DATE, DONOR_ID, ACCOUNT_NUMBER_100, COMPANY_NAME_100, FIRST_NAME, LAST_NAME, PHONE, STREET1, STREET2, STATE, CITY, ZIP_CODE, WAVE_NAME, EMAIL, ORIGINAL_EMAIL, CODE1, DISPOSITION_CODE, DESCRIPTION) AS

( SELECT CAMP_ABBR, CONVERT(VARCHAR,ORIG_CALL_DATE,101), DONOR_ID, ACCOUNT_NUMBER_100 作为 ACCOUNT_ID,COM​​PANY_NAME_100,FIRST_NAME, LAST_NAME,TEL_AREA_CODE + TEL_PREFIX + TEL_ROOT 作为电话, STREET1, STREET2, STATE, CITY, ZIP_CODE, WAVE_NAME, EMAIL、ORIGINAL_EMAIL、CODE1、DISPOSITIO'
不是有效的标识符。

看起来它已达到局部变量的 varchar 限制,但我不知道原因是什么。

【问题讨论】:

  • 您的 select 子句中有“R.DISPOSITION_CODE”和“D.DESCRIPTION”,但没有表别名为“r”或“d”
  • 从您发布的内容来看,首先没有理由使用动态 sql。这只会让事情变得更复杂。
  • Greenspark 他们是别名只是不是所有的代码都在这里代码在它自己的 CTE 之外工作我正在这样做所以我知道怎么做。
  • @CMO79 你的代码有很多错误。
  • 你已经定义了 CTE,但是你还没有从中选择任何东西.. 你基本上做了with cte as (select a from table).. 你需要像with cte as (select a from table) select * from cte一样使用cte

标签: sql-server stored-procedures common-table-expression dynamic-sql


【解决方案1】:

EXEC @SQL 应该是 EXEC (@SQL); 第一个给我的不是有效标识符。

谢谢

【讨论】:

  • 或者更好的是使用 exec sp_executesql @SQL
  • 我都试过了,然后在')'附近得到一个不正确的语法错误
  • 在 SELECT 语句中检查不必要的 ( and )?
【解决方案2】:

您需要将 AS 关键字移近 WITH 并且您需要重新格式化查询,类似于:

;with CTE_RESULT AS -- NOTE: AS moved here
(
    SELECT
        CAMP_ABBR,
        ORIG_CALL_DATE,
        DONOR_ID,
        ACCOUNT_NUMBER_100,
        COMPANY_NAME_100,
        FIRST_NAME,
        LAST_NAME,
        PHONE,
        STREET1,
        STREET2,
        STATE,
        CITY,
        ZIP_CODE,
        WAVE_NAME,
        EMAIL,
        ORIGINAL_EMAIL,
        CODE1,
        DISPOSITION_CODE,
        DESCRIPTION
    FROM placeholder1 t1
    WHERE COLUMN IN(''01'',''02'')
) -- AS -- this AS here should be causing the error.
SELECT * FROM CTE_RESULT

在此处阅读有关公用表表达式语法的更多信息:WITH common_table_expression

【讨论】:

  • 有希望,但在删除初始 AS 并向上移动之后。现在出现语法错误。对于第一个字段 camp_abbr。
  • @CMO79 是的,因为你需要重写整个事情。请注意,您声明了CTE_RESULT,但从不声明JOINSELECT
  • 这就是我需要实现的。应该足以修复语法我对这个答案很满意。谢谢!
  • @CMO79 我已使用建议的格式更新了查询。看看你是否能完全适应你的上下文。
【解决方案3】:

正在执行局部变量,但未通过从填充在局部变量中的 CTE 中选择修复的 CTE 进行选择。 :

DECLARE @STARTDATE DATETIME,
        @ENDDATE DATETIME,
        @SQL nVARCHAR(max)

SET @SQL = '
;with CTE_RESULT  
(
        CAMP_ABBR,
        ORIG_CALL_DATE,
        DONOR_ID,
        ACCOUNT_NUMBER_100,
        COMPANY_NAME_100,
        FIRST_NAME,
        LAST_NAME,
        PHONE,
        STREET1,
        STREET2,
        STATE,
        CITY,
        ZIP_CODE,
        WAVE_NAME,
        EMAIL,
        ORIGINAL_EMAIL,
        CODE1,
        DISPOSITION_CODE,
        DESCRIPTION 
)
AS
(
SELECT  M.CAMP_ABBR,
        CONVERT(VARCHAR,ORIG_CALL_DATE,101),
        DONOR_ID,
        ACCOUNT_NUMBER_100 AS ACCOUNT_ID,
        COMPANY_NAME_100,
        FIRST_NAME,
        LAST_NAME,
        TEL_AREA_CODE + TEL_PREFIX + TEL_ROOT AS PHONE,
        STREET1,
        STREET2,
        STATE,
        CITY,
        ZIP_CODE,
        WAVE_NAME,
        EMAIL,
        ORIGINAL_EMAIL,
        CODE1,
        R.DISPOSITION_CODE,
        D.DESCRIPTION 
FROM CMSPRD18.CAMP.DBO.GHIL0001_MAS M
LEFT JOIN CMSPRD18.CAMP.DBO.GHIL0001_RES R
ON M.UNIQUE_NUMBER = R.UNIQUE_NUMBER
JOIN [ADMIN].[DBO].[CAMPAIGN] C 
ON M.CAMP_ABBR = C.CAMP_ABBR
JOIN [ADMIN].[DBO].DISPOSITION D 
ON C.CAMP_ID = D.CAMP_ID
AND R.DISPOSITION_CODE = D.DISPOSITION_CODE
WHERE R.DISPOSITION_CODE IN(''01'',''02''))

SELECT * 
FROM CTE_RESULT

'

执行 (@SQL)

这就是我想要通过转换实现的目标。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-02-17
    • 1970-01-01
    • 1970-01-01
    • 2012-05-31
    • 2013-05-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多