Ich habe ein paar Probleme mit der Übergabe eines Nullable-Parameters an eine gespeicherte Prozedur, die dynamische Abfragen verwendet, um eine Tabelle auszuführen.SQL Server: Übergabe von Nullable-Parametern an eine gespeicherte Prozedur mit dynamischer Abfrage
Ich muss in der Lage sein, null an alle Parameter zu übergeben, die Nullable sein können. Wenn ich diesen Code aus dynamischem SQL herausnehme, funktioniert es gut.
Der Code:
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
Die Tabelle:
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]
Sie verwenden 'sp_executesql'. Verwenden Sie es nun korrekt und übergeben Sie die Werte als * parameters *, anstatt die Abfrage SQL-Injection- und potenziellen Syntaxfehlern auszusetzen. –
Das Problem sieht so aus, als wollten Sie überprüfen, ob "NULL" (als String) null ist (nicht). Du könntest etwas wie '' '' + ISNULL (@var, '') + '' '=' '' 'oder so ähnlich machen. Oder was Gordon mit den richtigen Parametern gesagt hat. – ZLK
sollten Sie die Option RECOMPILE für diese gespeicherte Prozedur verwenden, https://msdn.microsoft.com/en-ie/library/ms190439.aspx – Jodrell