it-swarm.com.de

Parameter für gespeicherte Prozedur null in der where-Klausel

Ich möchte einen Parameter in der where-Klausel nur verwenden, wenn sein Wert von einem stark typisierten Dataset bereitgestellt wird. Dies ist das, was ich im Moment versuche. Ich erhalte die richtigen Ergebnisse, wenn ich parameter3 und keine Ergebnisse, wenn ich den Wert nicht zur Verfügung stelle.

Was ich wünsche, ist, wenn ich keinen Wert für parameter3, es sollte nicht in der Abfrage verwendet werden, da der Wert null ist und ich alle Ergebnisse in der Abfrage sehen möchte, nicht where Paramerter3 = null Einsen:

ALTER procedure [dbo].[GetData]
(
    @Parameter1 varchar(256),
    @Parameter2 varchar(256),
    @Parameter3 int = null
)
AS

SELECT
    *
FROM
    Table1
WHERE
    Table1.URL LIKE '%' + @Parameter1 + '%' 
    AND Table1.ID = @Parameter2
    AND (@Parameter3 IS NULL OR Table1.ID2 = @Parameter3)
ORDER BY
    Table1.Title

Bearbeiten: Ich habe versucht, Thomas zu antworten und wie folgt ausgeführt:

EXEC @return_value = [dbo].[GetData]
                              @Parameter1 = N'asda',
                              @Parameter2 = N'asda',
                              @Parameter3 = null

SELECT  'Return Value' = @return_value
GO

Ich habe auch die gespeicherte Prozedur aktualisiert, wie Thomas sagte.

5
Mathematics
SELECT *
FROM Table1
WHERE Table1.URL LIKE '%' + @Parameter1 + '%' AND Table1.ID = @Parameter2
AND 
(
    @Parameter3 is null 
    or Table1.ID2 = @Parameter3
);

Schauen Sie sich das obige Beispiel an. Wenn Sie Ihre AND-Klausel in eine verschachtelte OR -Klausel, die Ihren Anfangsausdruck angibt, sowie @Parameter3 is null Ändern, wird dann verlangt, dass der verschachtelte Ausdruck wahr ist, wenn @ Parameter3 NULL ist.

14
Thomas Stringer

Ich war schon immer ein Fan eines dynamischen SQL-Ansatzes für diese Art von Problem. Ich finde, es bietet das optimale Gleichgewicht zwischen Komplexität und Qualitätsabfrageplan.

Im folgenden Code definiere ich eine Basisabfrage, die alles tut, was erforderlich ist, und füge die Filter dann nur hinzu, wenn der angegebene Parameter nicht null ist.

CREATE PROCEDURE [dbo].[GetData]
(
    @Parameter1 varchar(256),
    @Parameter2 varchar(256),
    @Parameter3 int = null
)
AS
BEGIN
    SET NOCOUNT ON;
    DECLARE 
        @BaseQuery nvarchar(max) = N'SELECT T.* FROM dbo.Table1 AS T'
    ,   @ParamList nvarchar(max) = N'@p1 varchar(256), @p2 varchar(256), @p3 int'
    ,   @WhereClause nvarchar(max) = ' WHERE 1=1';

    IF @Parameter1 IS NOT NULL
    BEGIN
        SET @WhereClause = @WhereClause + ' AND T.Url = @p1';
    END

    IF @Parameter2 IS NOT NULL
    BEGIN
        SET @WhereClause = @WhereClause + ' AND T.ID = @p2';
    END

    IF @Parameter3 IS NOT NULL
    BEGIN
        SET @WhereClause = @WhereClause + ' AND T.ID2 = @p3';
    END

    SET @BaseQuery = @BaseQuery + @WhereClause;

    EXECUTE sp_executesql @BaseQuery, @ParamList, @p1 = @Parameter1, @p2 = @Parameter2, @p3 = @Parameter3;
END
12
billinkc

Es kann tatsächlich viel einfacher sein:

SELECT *
FROM Table1
WHERE Table1.URL LIKE '%' + @Parameter1 + '%' AND Table1.ID = @Parameter2
  AND Table1.ID2 = ISNULL(@Parameter3, Table1.ID2)

Hinweis: Ich habe den Kommentar von ConcernedOfTunbridgeWells nicht gesehen, als ich die Antwort geschrieben habe. Ich habe meine Antwort gelöscht, als ich es herausfand. Aber beim zweiten Gedanken könnte ich es einfach behalten und hoffen, dass es anderen hilft. "Wobei @parameter null oder ... ist" macht keinen Sinn, obwohl es möglicherweise funktioniert. Die Verwendung von dynamischem SQL ist übertrieben. Ich verwende den folgenden Code für MS SQL und Sybase ziemlich oft, um zu überprüfen, ob ein Parameter null oder leer ist:

SELECT * 
FROM tblName 
WHERE [ColumnName] = ISNULL(NULLIF(@parameter, ''), [ColumnName])
  AND ('something else here')
0
Weihui Guo