不能投于CTE

时间:2017-05-31 15:14:04

标签: sql tsql syntax casting sql-server-2016

我很好奇为什么我会因为施放#34; tmp"而导致语法错误。 dataitem 就是这样

;WITH tmp(date, CAST(dataitem AS VARCHAR(255)), data) AS
(
    SELECT 
        date, LEFT(msg, CHARINDEX(';', msg + ';') - 1),  
        STUFF(msg, 1, CHARINDEX(';', msg + ';'), '')   
    FROM
        DB1 
    WHERE
        action LIKE 'FILE UPLOAD FTP' 
        AND date BETWEEN '06/01/2016' AND '07/05/2017'

    UNION ALL

    SELECT 
        date, CHARINDEX(';', data + ';'),  
        STUFF(data, 1, CHARINDEX(';', Data + ';'), '') 
    FROM
        tmp 
    WHERE
        data > ''
)
SELECT 
    date, dataitem, 
    REPLACE(SUBSTRING(dataitem, 1, CHARINDEX('|', dataitem) - 1), 'FTP UPLOAD: ', '') AS orig_file_name, 
    SUBSTRING(dataitem, CHARINDEX('|', dataitem) + 1, 8000) AS file_name,
    (SELECT TOP 1 counts FROM DB1 
     WHERE action LIKE 'FILTER' AND date > tmp.date 
       AND msg LIKE SUBSTRING(tmp.dataitem, CHARINDEX('|', dataitem ) + 1, 8000) + '%' 
     ORDER BY date) AS filter_counts,
FROM 
    tmp
ORDER BY 
    date

考虑到这种方法有效,但由于数据类型不匹配会导致错误:

;WITH tmp(date, dataitem , data) AS 
(
    SELECT 
        date, LEFT(msg, CHARINDEX(';', msg + ';') - 1),  
        STUFF(msg, 1, CHARINDEX(';', msg + ';'), '')   
    FROM
        DB1 
    WHERE
        action LIKE 'FILE UPLOAD FTP' 
        AND date BETWEEN '06/01/2016' AND '07/05/2017'

    UNION ALL

    SELECT 
        date,  CHARINDEX(';', data + ';'),  
        STUFF(data, 1, CHARINDEX(';', Data + ';'), '') 
    FROM
        tmp 
    WHERE
        data > ''
)
SELECT 
    date, dataitem, 
    REPLACE(SUBSTRING(dataitem, 1, CHARINDEX('|', dataitem) - 1), 'FTP UPLOAD: ', '') AS orig_file_name, 
    SUBSTRING(dataitem, CHARINDEX('|', dataitem) + 1, 8000) AS file_name,
    (SELECT TOP 1 counts FROM DB1 
     WHERE action LIKE 'FILTER' 
       AND date> tmp.date 
       AND msg LIKE SUBSTRING(tmp.dataitem, CHARINDEX('|', dataitem ) + 1, 8000) + '%' 
     ORDER BY date) AS filter_counts,
FROM
    tmp
ORDER BY 
    date

1 个答案:

答案 0 :(得分:1)

当然,您可以在CTE中使用CAST,仅在SELECT列表中,而不是在列列表中:

WITH tmp(date, dataitem , data) AS (
     SELECT date, 
            CAST (LEFT(msg, CHARINDEX(';',msg+';')-1) AS VARCHAR(255)),  
            STUFF(msg, 1, CHARINDEX(';',msg+';'), '')   
     FROM DB1
     ...