Załóżmy, że masz procedurę składowaną i przyjmuje ona opcjonalny parametr. Chcesz użyć tego opcjonalnego parametru w zapytaniu SQL. Zazwyczaj jest to jak widziałem to zrobić:Właściwy sposób obsługi "opcjonalnego", gdzie filtry klauzuli w SQL?
SELECT * FROM dbo.MyTableName t1
WHERE t1.ThisField = 'test'
AND (@MyOptionalParam IS NULL OR t1.MyField = @MyOptionalParam)
To wydaje się działać dobrze, jednak powoduje to dużą ilość logicznych odczytów, jeśli uruchomić kwerendę statystyki IO. Próbowałem również następujący wariant:
SELECT * FROM dbo.MyTableName t1
WHERE t1.ThisField = 'test'
AND t1.MyField = CASE WHEN @MyOptionalParam IS NULL THEN t1.MyField ELSE @MyOptionalParam END
I daje taką samą liczbę wysokich odczytów. Jeśli będziemy konwertować SQL do łańcucha, a następnie zadzwonić sp_executesql na nim odczyty są prawie zerowe:
DECLARE @sql nvarchar(max)
SELECT @sql = 'SELECT * FROM dbo.MyTableName t1
WHERE t1.ThisField = ''test'''
IF @MyOptionalParam IS NOT NULL
BEGIN
SELECT @sql = @sql + ' AND t1.MyField = @MyOptionalParam '
END
EXECUTE sp_ExecuteSQL @sql, N'@MyOptionalParam', @MyOptionalParam
jestem szalony? Dlaczego opcjonalnie klauzule są tak trudne do uzyskania?
Aktualizacja: Ja w zasadzie pytaniem, czy istnieje sposób, aby zachować standardową składnię wewnątrz procedury przechowywanej i uzyskać niski logiczne brzmi jak metoda sp_executesql robi. Wydaje się całkowicie szalony mi zbudować ciąg ... nie wspominając to sprawia, że trudniej utrzymać, debugowania, wizualizacji ..
Nicholas, zobacz poniższe podejście do unii w celu zastosowania standardowej składni sql bez dynamicznego sql - Byłbym bardzo ciekawy, aby zobaczyć, jak publikujesz swoje wyniki w swoim scenariuszu ... – chadhoc
@Nicholas: Konstruowanie zapytania jako ciąg przed wykonaniem jest ** dokładnie ** czym * dynamiczny * SQL jest. Jest to niewielki problem podczas debugowania - kopiowania/wklejania, pozbycia się składni połączenia ciągów. –