SQL Server:使用动态查询

时间:2016-08-01 01:13:36

标签: sql sql-server stored-procedures dynamic

我在将可以为空的参数传递给使用动态查询来运行表的存储过程时遇到了一些麻烦。

我需要做的是将null传递给所有可以为空的参数。如果我从动态SQL中获取此代码,则可以正常工作。

代码:

ALTER proc [dbo].[TEST_spExtractNL_Dynamic]
    @StartDate date,
    @Company nvarchar(1) = null,
    @Location1 nvarchar(1) = null,
    @Location2 nvarchar(1) = null,
    @Department nvarchar(1) = null,
    @P1 nvarchar(1) = null,
    @P2 nvarchar(1) = null,
    @P3 nvarchar(1) = null,
    @P4 nvarchar(1) = null,
    @P5 nvarchar(1) = null,
    @P6 nvarchar(1) = null,
    @P7 nvarchar(1) = null,
    @P8 nvarchar(1) = null
as
begin
    Create table #TempTable
    (
        [Type] [float] NOT NULL,
        [Description] [nvarchar](100) NOT NULL
    )

    DECLARE @DynamicQuery_CurrentActual AS NVARCHAR(MAX)
    SET @DynamicQuery_CurrentActual = N'SELECT
                                           SUM([Budget]) * -1 as [Type],
                                           ''Current Actual'' as  [Description]
                                        FROM [TS_Group_Reports].[dbo].[SDCG_FINREP_DataDump]
                                        WHERE
    [Date] BETWEEN ''' + CONVERT(VARCHAR(10),DATEFROMPARTS(YEAR(@StartDate),MONTH(@StartDate),1), 101) + ''' AND ''' + CONVERT(VARCHAR(10),EOMONTH(@StartDate), 101) + '''
    AND
    (''' + @Company + ''' IS NULL OR (SUBSTRING(CAST([Accont] as nvarchar(12)),1,1) = ''' + @Company + '''))
    AND
    (''' + @Location1 + ''' IS NULL OR (SUBSTRING(CAST([Accont] as nvarchar(12)),2,1) = ''' + @Location1 + '''))
    AND
    (''' + @Location2 + ''' IS NULL OR (SUBSTRING(CAST([Accont] as nvarchar(12)),3,1) = ''' + @Location2 + '''))
    AND
    (''' + @Department + ''' IS NULL OR (SUBSTRING(CAST([Accont] as nvarchar(12)),4,1) = ''' + @Department + '''))

    AND
    (''' + @P1 + ''' IS NULL OR (SUBSTRING(CAST([Accont] as nvarchar(12)),5,1) = ''' + @P1 + '''))
    AND
    (''' + @P2 + ''' IS NULL OR (SUBSTRING(CAST([Accont] as nvarchar(12)),6,1) = ''' + @P2 + '''))
    AND
    (''' + @P3 + ''' IS NULL OR (SUBSTRING(CAST([Accont] as nvarchar(12)),7,1) = ''' + @P3 + '''))
    AND
    (''' + @P4 + ''' IS NULL OR (SUBSTRING(CAST([Accont] as nvarchar(12)),8,1) = ''' + @P4 + '''))
    AND
    (''' + @P5 + ''' IS NULL OR (SUBSTRING(CAST([Accont] as nvarchar(12)),9,1) = ''' + @P5 + '''))
    AND
    (''' + @P6 + ''' IS NULL OR (SUBSTRING(CAST([Accont] as nvarchar(12)),10,1) = ''' + @P6 + '''))
    AND
    (''' + @P7 + ''' IS NULL OR (SUBSTRING(CAST([Accont] as nvarchar(12)),11,1) = ''' + @P7 + '''))
    AND
    (''' + @P8 + ''' IS NULL OR (SUBSTRING(CAST([Accont] as nvarchar(12)),12,1) = ''' + @P8 + '''))
    AND
    [Type] like ''_A'''

DECLARE @DynamicQuery_CurrentBudget AS NVARCHAR(MAX)
SET @DynamicQuery_CurrentBudget =
N'SELECT
    sum([Budget]) * -1 as [Type]
    ,''Current Budget'' as [Description]
FROM [TS_Group_Reports].[dbo].[SDCG_FINREP_DataDump]
WHERE
    [Date] BETWEEN ''' + CONVERT(VARCHAR(10),DATEFROMPARTS(YEAR(@StartDate),MONTH(@StartDate),1), 101) + ''' AND ''' + CONVERT(VARCHAR(10),EOMONTH(@StartDate), 101) + '''
    AND
    (''' + @Company + ''' IS NULL OR (SUBSTRING(CAST([Accont] as nvarchar(12)),1,1) = ''' + @Company + '''))
    AND
    (''' + @Location1 + ''' IS NULL OR (SUBSTRING(CAST([Accont] as nvarchar(12)),2,1) = ''' + @Location1 + '''))
    AND
    (''' + @Location2 + ''' IS NULL OR (SUBSTRING(CAST([Accont] as nvarchar(12)),3,1) = ''' + @Location2 + '''))
    AND
    (''' + @Department + ''' IS NULL OR (SUBSTRING(CAST([Accont] as nvarchar(12)),4,1) = ''' + @Department + '''))

    AND
    (''' + @P1 + ''' IS NULL OR (SUBSTRING(CAST([Accont] as nvarchar(12)),5,1) = ''' + @P1 + '''))
    AND
    (''' + @P2 + ''' IS NULL OR (SUBSTRING(CAST([Accont] as nvarchar(12)),6,1) = ''' + @P2 + '''))
    AND
    (''' + @P3 + ''' IS NULL OR (SUBSTRING(CAST([Accont] as nvarchar(12)),7,1) = ''' + @P3 + '''))
    AND
    (''' + @P4 + ''' IS NULL OR (SUBSTRING(CAST([Accont] as nvarchar(12)),8,1) = ''' + @P4 + '''))
    AND
    (''' + @P5 + ''' IS NULL OR (SUBSTRING(CAST([Accont] as nvarchar(12)),9,1) = ''' + @P5 + '''))
    AND
    (''' + @P6 + ''' IS NULL OR (SUBSTRING(CAST([Accont] as nvarchar(12)),10,1) = ''' + @P6 + '''))
    AND
    (''' + @P7 + ''' IS NULL OR (SUBSTRING(CAST([Accont] as nvarchar(12)),11,1) = ''' + @P7 + '''))
    AND
    (''' + @P8 + ''' IS NULL OR (SUBSTRING(CAST([Accont] as nvarchar(12)),12,1) = ''' + @P8 + '''))
    AND
    [Type] like ''_B'''

    insert into #TempTable
       EXEC sp_executesql @DynamicQuery_CurrentActual

    insert into #TempTable
       EXEC sp_executesql @DynamicQuery_CurrentBudget

    select * 
    from #TempTable
END

表格:

CREATE TABLE [dbo].[SDCG_FINREP_DataDump]
(
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [Accont] [bigint] NOT NULL,
    [Description] [nvarchar](100) NOT NULL,
    [Date] [date] NOT NULL,
    [Budget] [float] NOT NULL,
    [Type] [nvarchar](5) NOT NULL,

    CONSTRAINT [PK_SDCG_FINREP_DataDump] 
       PRIMARY KEY CLUSTERED
 ) ON [PRIMARY]

1 个答案:

答案 0 :(得分:1)

您应该使用sp_executesql参数。这里我只展示一个参数@Company

SET @DynamicQuery_CurrentBudget =
N'SELECT
    sum([Budget]) * -1 as [Type]
    ,''Current Budget'' as [Description]
FROM [TS_Group_Reports].[dbo].[SDCG_FINREP_DataDump]
WHERE
    [Date] BETWEEN ''' + CONVERT(VARCHAR(10),DATEFROMPARTS(YEAR(@StartDate),MONTH(@StartDate),1), 101) + ''' AND ''' + CONVERT(VARCHAR(10),EOMONTH(@StartDate), 101) + '''
    AND
    ('@Company IS NULL OR (SUBSTRING(CAST([Accont] as nvarchar(12)),1,1) =  @Company))

然后使用带参数的sp_executesql

EXEC sp_executesql @DynamicQuery_CurrentActual, N'@Company nvarchar(1)', @Company