2017-01-18 14 views
2

Ich versuche, folgende dynamische Abfrage ausführen, ich habe gerade dynamische Parameter an diese Abfrage übergeben.Wie Null-Wert in dynamische Abfrage übergeben

DECLARE @TABLE TABLE(ID INT,NAME VARCHAR(10)) 
INSERT INTO @TABLE 
SELECT 1,'A' 
UNION 
SELECT 2,'B' 
UNION 
SELECT 3,NULL 

DECLARE @NAME VARCHAR(20)=NULL, 
     @SQL VARCHAR(MAX) 
     SET @SQL='SELECT * 
        FROM @TABLE 
        WHERE NAME='''[email protected]+'''' 
PRINT @SQL 

Aber ich kann keine Ergebnisse oder Fehler erhalten. tut jemand, um dieses Problem zu sortieren.

+0

Sie ISNULL verwenden können, um @name, becasue NULL Kontakt mit einem beliebigen Wert wird noch NULL ist –

+0

Warum gibt es überhaupt dynamische SQL? –

+0

Bitte klären Sie, wenn Sie absichtlich einen NULL-Wert an die Abfrage übergeben möchten oder sich fragen, warum die Abfrage fehlschlägt. Wenn Sie einen NULL übergeben möchten, müssen wir die Zeichenfolge ändern, da der NULL-Vergleich nicht mit dem Operator '=' durchgeführt werden soll. – DK5

Antwort

0

Wenn Sie eine NULL mit einer Zeichenfolge verketten, erhalten Sie immer nur eine NULL. Hier ist die Variable @NAME NULL, also wird auch NULL sein.

Sie können die Funktion ISNULL verwenden, um einen Standardwert zuzuweisen, wenn @NAME NULL ist.

SET @SQL='SELECT * 
      FROM @TABLE 
      WHERE ISNULL(NAME,'''')='''+ISNULL(@NAME,'')+'''' 

Aber ein anderes Problem in der Abfrage ist, Sie können keine @Table_Variable innerhalb einer dynamischen SQL-, den Fehler aus, fügen Sie, wenn Sie die Abfrage ausführen, aber Sie können #Temp_tables hier verwenden.

0

Es gibt zwei Probleme mit dem Skript

1) Sie setzen Ihre Variable @Name auf NULL. Wenn Sie jetzt eine NULL mit einer VARCHAR-Variablen verketten, wird Ihr Ergebnis zu einer NULL-Zeichenfolge. Wenn Ihre Variable @SQL, die die SELECT-Anweisung enthält, mit @Name verkettet wird, wird sie NULL, und wenn Sie sie mit EXECUTE verwenden, gibt Ihre Antwort nichts zurück.

2) Sie deklarieren eine Tabellenvariable, die nicht im Geltungsbereich der EXECUTE-Anweisung enthalten ist. Wenn Sie Variablen mit dynamischem SQL verwenden, müssen sie entweder:

  1. verketteten mit der Zeichenfolge, wie Sie mit @Name Variable versuchten tun, in diesem Fall der Wert der Variablen übergeben wird und der Wert wird zu einem Teil von die Zeichenfolge anstelle der variablen DECLARE @Name VARCHAR(20) = 'ABC'; EXEC('SELECT ''' + @Name + ''';');

die obige Aussage wird die folgende SQL-Äquivalent auszuführen:

SELECT 'ABC'; 
  1. The other Möglichkeit, eine Variable als eine Variable innerhalb der dynamischen SQL-Anweisung zu verwenden, besteht darin, diese Variable nur innerhalb des dynamischen SQL zu deklarieren. Andernfalls wird die Variable nicht innerhalb des dynamischen SQL erkannt und Sie erhalten einen nicht deklarierten Fehler bei der Ausführung Ihrer SQL-Zeichenfolge. Wie Sie sehen, wenn Sie Ihre Anweisung ausführen, kann SQL die Tabellenvariable @Table nicht von innen erkennen. Die Abhilfe für dieses ist die @Table Variable innerhalb der dynamischen SQL-Zeichenfolge deklarieren und es dort zu initialisieren: DECLARE @NAME VARCHAR(20)=NULL, @SQL VARCHAR(MAX); SET @SQL='DECLARE @TABLE TABLE(ID INT,NAME VARCHAR(10)) INSERT INTO @TABLE SELECT 1,''A'' UNION SELECT 2,''B'' UNION SELECT 3,NULL; SELECT * FROM @TABLE WHERE NAME='''[email protected]+'''';

Eine wichtige Sache zu erinnern ist, dass, wird die dynamische SQL-Zeichenfolge in einem separaten Batch von der ausgeführt werden eine, in der es hieß. Das bedeutet, dass wenn wir die Variable @Table innerhalb der dynamischen SQL-Zeichenfolge deklarieren, diese nur für die Dauer und den Umfang der dynamischen SQL-Zeichenfolge existiert und danach nicht mehr existiert. Daher sind alle Änderungen, die Sie an der Variablen @Table vornehmen, nach der dynamischen SQL-Anweisung nicht mehr vorhanden, da die Variable @Table nicht mehr vorhanden ist. Wenn die @Table-Variable außerhalb der SQL-Zeichenfolge deklariert wird, wird ihre Verwendung im dynamischen @ SQL-Batch verhindert.

0

Sie können nicht auf Tabellenvariable in EXEC Anweisung zugreifen.Da die Tabellenvariable für den Verbindungsbereich spezifisch ist. Und Exec-Anweisung wird den Code in einer anderen Sitzung (Verbindung) ausführen.

Anstatt also können Sie temporäre Tabelle (#)

CREATE TABLE #TABLE (ID INT,NAME VARCHAR(10)) 
INSERT INTO #TABLE 
SELECT 1,'A' 
UNION 
SELECT 2,'B' 
UNION 
SELECT 3,NULL 

DECLARE @NAME VARCHAR(20)=NULL, 
     @SQL VARCHAR(MAX) 
     SET @SQL='SELECT * 
        FROM #TABLE 
        WHERE NAME ' 
SELECT @SQL = @SQL + CASE WHEN @NAME IS NULL THEN 'IS NULL' ELSE '='''[email protected]+'''' END 
PRINT @SQL 
0

Vielmehr verwenden als die Zeichenfolge zusammen verketten, fügte ich eine Set-Anweisung die @NAME Variable entweder mit dem String-Wert zu ersetzen oder IS NULL.

DECLARE @TABLE TABLE(ID INT,NAME VARCHAR(10)) 
INSERT INTO @TABLE 
SELECT 1,'A' 
UNION 
SELECT 2,'B' 
UNION 
SELECT 3,NULL 

DECLARE @NAME VARCHAR(20)=NULL, 
     @SQL VARCHAR(MAX) 
     SET @SQL='SELECT * 
        FROM @TABLE 
        WHERE NAME [NAME]' 
set @SQL = replace(@SQL, '[NAME]', isnull('= ''' + @NAME + '''', 'IS NULL')) 
print @SQL