1

我正在尝试将复杂查询的结果存储在临时表中,但我不断收到错误消息。以下是我的存储过程中的代码:

DECLARE @TempItems TABLE
(
ID int IDENTITY, ForumThreadID int, ForumID int, ParentID int, title NVARCHAR(MAX), title_path NVARCHAR(MAX), 
level_id NVARCHAR(MAX), level_id_path NVARCHAR(MAX), PostBody NVARCHAR(MAX), CreatedBy int, UserName NVARCHAR(50), Created DateTime
)

DECLARE @SQL NVARCHAR(MAX)

SET @SQL = 'WITH TreeList (ForumThreadID, ForumID, ParentID, title, title_path, level_id, level_id_path) as 
    ( 
    SELECT p.ForumThreadID,  
    p.ForumID, 
    p.ParentID,  
    p.PostSubject,  
    CONVERT(nvarchar(max), p.ForumThreadID),  
    ROW_NUMBER() OVER(PARTITION BY ParentID ORDER BY p.ForumThreadID),  
    RIGHT(''0000'' + CAST(ROW_NUMBER() OVER(PARTITION BY ParentID ORDER BY p.ForumThreadID) AS varchar(max)),4)  
    FROM ForumThreads p 
    WHERE (p.ParentID = ' + @ParentID + ') AND (p.Deleted IS NULL) 
    UNION ALL 
    SELECT c.ForumThreadID,  
    c.ForumID,  
    c.ParentID,  
    c.PostSubject,  
    r.title_path + ''/'' + CAST(c.ForumThreadID AS VARCHAR(MAX)),  
    ROW_NUMBER() OVER(PARTITION BY c.ParentID ORDER BY c.ForumThreadID),  
    CONVERT(varchar(max), r.level_id_path + ''.'' + RIGHT(''0000'' + CAST(ROW_NUMBER() OVER(PARTITION BY c.ParentID ORDER BY c.ForumThreadID) AS VARCHAR),4))  
    FROM ForumThreads AS c 
    INNER JOIN treelist AS r 
    ON c.ParentID = r.ForumThreadID 
    WHERE (c.Deleted IS NULL)) 
    SELECT TOP 100 TreeList.*, d.PostBody, d.CreatedBy, Members.UserName, COALESCE(d.Created,''1-JAN-1900'') AS Created 
    FROM TreeList INNER JOIN ForumThreads AS d ON TreeList.ForumThreadID = d.ForumThreadID INNER JOIN 
    Members ON d.CreatedBy = Members.MemberID 
    WHERE (d.Deleted IS NULL) 
    ORDER BY level_id_path;'

INSERT INTO @TempItems (ForumThreadID, ForumID, ParentID, title, title_path, level_id, level_id_path, PostBody, CreatedBy, UserName, Created) EXEC @SQL

SELECT * FROM @TempItems

我得到的错误是:

Msg 203, Level 16, State 2, Procedure spPagedForumThreads, Line 53
The name 'WITH TreeList (ForumThreadID, ForumID, ParentID, title, title_path, level_id, level_id_path) as 
( 
SELECT p.ForumThreadID,  
p.ForumID, 
p.ParentID,  
p.PostSubject,  
CONVERT(nvarchar(max), p.ForumThreadID),  
ROW_NUMBER() OVER(PARTITION BY ParentID ORDER BY p.ForumThreadID),  
RIGHT('0000' + CAST(ROW_NUMBER() OVER(PARTITION BY ParentID ORDER BY p.ForumThreadID) AS varchar(max)),4)  
FROM ForumThreads p 
WHERE (p.ParentID = 10720) AND (p.Deleted IS NULL) 
UNION ALL 
SELECT c.ForumThreadID,  
c.ForumID,  
c.ParentID,  
c.PostSubject,  
r.title_path + '/' + ' is not a valid identifier.

我究竟做错了什么?

是否有另一种创建临时表的方法,不需要将查询保存为字符串?

谢谢!

4

2 回答 2

1

执行动态 SQL 的目的是什么?在您的 CTE 之后,您应该能够将您的SELECT声明修改为INSERT INTO @TempItems SELECT TOP 100 TreeList.* .....

这应该可以在不需要动态 SQL(即EXEC)的情况下工作。注意前面的语句WITH需要用分号终止,以便在语法上有效。

DECLARE @TempItems TABLE
(
ID int IDENTITY, ForumThreadID int, ForumID int, ParentID int, title NVARCHAR(MAX), title_path NVARCHAR(MAX), 
level_id NVARCHAR(MAX), level_id_path NVARCHAR(MAX), PostBody NVARCHAR(MAX), CreatedBy int, UserName NVARCHAR(50), Created DateTime
);

WITH TreeList (ForumThreadID, ForumID, ParentID, title, title_path, level_id, level_id_path) as 
    ( 
    SELECT p.ForumThreadID,  
    p.ForumID, 
    p.ParentID,  
    p.PostSubject,  
    CONVERT(nvarchar(max), p.ForumThreadID),  
    ROW_NUMBER() OVER(PARTITION BY ParentID ORDER BY p.ForumThreadID),  
    RIGHT('0000' + CAST(ROW_NUMBER() OVER(PARTITION BY ParentID ORDER BY p.ForumThreadID) AS varchar(max)),4)  
    FROM ForumThreads p 
    WHERE (p.ParentID = ' + @ParentID + ') AND (p.Deleted IS NULL) 
    UNION ALL 
    SELECT c.ForumThreadID,  
    c.ForumID,  
    c.ParentID,  
    c.PostSubject,  
    r.title_path + '/' + CAST(c.ForumThreadID AS VARCHAR(MAX)),  
    ROW_NUMBER() OVER(PARTITION BY c.ParentID ORDER BY c.ForumThreadID),  
    CONVERT(varchar(max), r.level_id_path + '.' + RIGHT('0000' + CAST(ROW_NUMBER() OVER(PARTITION BY c.ParentID ORDER BY c.ForumThreadID) AS VARCHAR),4))  
    FROM ForumThreads AS c 
    INNER JOIN treelist AS r 
    ON c.ParentID = r.ForumThreadID 
    WHERE (c.Deleted IS NULL)) 

INSERT INTO @TempItems (ForumThreadID, ForumID, ParentID, title, title_path, level_id, level_id_path, PostBody, CreatedBy, UserName, Created)
    SELECT TOP 100 TreeList.*, d.PostBody, d.CreatedBy, Members.UserName, COALESCE(d.Created,'1-JAN-1900') AS Created 
    FROM TreeList INNER JOIN ForumThreads AS d ON TreeList.ForumThreadID = d.ForumThreadID INNER JOIN 
    Members ON d.CreatedBy = Members.MemberID 
    WHERE (d.Deleted IS NULL) 
    ORDER BY level_id_path;


SELECT * FROM @TempItems
于 2013-10-31T17:33:08.663 回答
0

EXEC(@SQL)而不仅仅是EXEC @SQL.

于 2013-10-31T17:24:49.163 回答