SQL Server:如何在动态Select中插入变量

时间:2014-06-08 19:17:49

标签: sql sql-server stored-procedures dynamic dynamic-queries

我有一个存储过程,我想使其动态化,以便它可以处理不同的输入。 我得到了大部分动态程序,除了以下内容。

有人可以告诉我如何编写此部件以便在动态过程中使用它吗? 我只需要在每个变量之前加'++'吗?

INSERT INTO @temp
(
            dateRange
)
SELECT      @date0
UNION ALL
SELECT      @date1
UNION ALL
SELECT      @date2
UNION ALL
SELECT      @date3
UNION ALL
SELECT      @date4
UNION ALL
SELECT      @date5

修改 整个查询为FYI。在我做这个动态之前,它是正确的,所以我的猜测是我在这里有一些遗漏或不需要的引号或任何其他写作错误。 另外,我不确定最后一个嵌套查询中的Where条件是否正确写为动态。

ALTER PROCEDURE [dbo].[FetchHistoryCombined]
    @selection nvarchar(100),
    @date0 nvarchar(20),
    @date1 nvarchar(20),
    @date2 nvarchar(20),
    @date3 nvarchar(20),
    @date4 nvarchar(20),
    @date5 nvarchar(20)
AS
BEGIN   
    SET NOCOUNT ON;

    BEGIN

    DECLARE @sql nvarchar(max)

    SET @sql = N' DECLARE @temp AS TABLE
    (
                dateRange nvarchar(20)
    )
    DECLARE @temp2 AS TABLE
    (
                ranking int,
                item nvarchar(100),
                volume int
    )

    INSERT INTO @temp
    (
                dateRange
    )
    SELECT      ' + @date0 + '
    UNION ALL
    SELECT      ' + @date1 + '
    UNION ALL
    SELECT      ' + @date2 + '
    UNION ALL
    SELECT      ' + @date3 + '
    UNION ALL
    SELECT      ' + @date4 + '
    UNION ALL
    SELECT      ' + @date5 + '

    INSERT INTO @temp2
    (       
                ranking,
                item,
                volume
    )
    SELECT      Top 10 RANK() OVER(ORDER BY COUNT(*) desc, ' + @selection + ') [Rank],
                ' + @selection + ', 
                COUNT(*) AS volume
    FROM        LogEsc 
    WHERE       dateEsc LIKE ''' + @date0 + '%''
    AND         EID LIKE ''PE%''
    GROUP BY    ' + @selection + '
    ORDER BY    volume desc, ' + @selection + '

    SELECT      
                (
                        SELECT      A.item
                        FROM        @temp2 A
                        ORDER BY    A.ranking, A.item
                        FOR XML PATH(''''), ELEMENTS, TYPE
                ) AS top10,
                (       
                        SELECT      B.dateRange,
                                    (
                                            SELECT      C.item,
                                                        (
                                                                SELECT      COUNT(*) AS volume
                                                                FROM        LogEsc D
                                                                WHERE       D.' + @selection + ' = C.item
                                                                AND         D.EID LIKE ''PE%''
                                                                AND         D.dateEsc LIKE B.dateRange + ''%''
                                                                FOR XML PATH(''''), ELEMENTS, TYPE
                                                        )
                                            FROM        @temp2 C
                                            ORDER BY    C.ranking, C.item
                                            FOR XML PATH(''''), ELEMENTS, TYPE
                                    ) AS [dateRange/items]
                        FROM    @temp B
                        FOR XML PATH(''''), ELEMENTS, TYPE
                ) AS history
    FOR XML PATH(''ranking''), ELEMENTS, TYPE, ROOT(''ranks'')'

    EXEC(@sql)

    END
END

非常感谢,迈克。

1 个答案:

答案 0 :(得分:1)

基本上,你需要围绕日期常量的单引号。这是一个开始:

INSERT INTO @temp(dateRange)
SELECT      ''' + @date0 + '''
UNION ALL
SELECT      ''' + @date1 + '''
UNION ALL
. . .

SQL足够聪明,能够读取写在同一系统上的日期。请注意,如果您要更改系统或将其写入文件,您可能希望明确表示日期格式(使用convert()将其置于某种规范格式中)。