2017-03-16 1 views
1

Eine Tabelle enthält Sequenznummern und Zeitstempel und andere Daten. Eine gespeicherte Prozedur benötigt 2 Parameter und der Benutzer kann eine Nullsequenznummer übergeben.WHERE-Klausel auf einem der beiden Parameter

Das ist, was ich zu erreichen versuchen, aber es funktioniert nicht (sagt SQL falsche Syntax in der Nähe von>)

create proc dbo.MyProc(@SequenceNo int, @Timestamp datetime) as 
begin 
    select * from MyTable where 
     case when @SequenceNo is not null THEN SequenceNo > @SequenceNo 
       ELSE Timestamp > @Timestamp 
     end 
end 

Wie dies zu tun?

+0

Ich habe, aber ich dachte, dass es Standard-SQL- – CashCow

+0

Anstelle würde Wert zuweisen in 'THEN' Teil, warum überprüfen Sie Ausdruck für größer als?, Sie können eine wahre False, 1 oder 0, oder einen anderen Wert Ihrer Wahl hier – Saurabh

+0

zuweisen Es soll bedeuten, dass, wenn & SequenceNo nicht null dann ist Verwenden Sie dies als Grundlage für die Bedingung, andernfalls verwenden Sie Timestamp. SequenceNo> & SequenceNo sollte eine Bedingung von True oder False zurückgeben. Wenn false, möchte ich, dass diese Zeile übersprungen wird. Ich möchte keine weiteren Fälle versuchen. (ersetzen & mit dir wissen, was) – CashCow

Antwort

2

Sie können den Code unten verwenden. Es verwendet eine Case-Anweisung in where-Klausel:

declare proc.MyProc(@SequenceNo int, @Timestamp datetime) as 
begin 
    select * 
    from MyTable 
    where 
     1 = case 
       when @SequenceNo is not null and SequenceNo > @SequenceNo then 1 
       when @SequenceNo is null and Timestamp > @Timestamp then 1 
       else 0 
      end 
end 
+0

Etwas wie das, was ich suchte, aber nicht funktioniert. Sieht nach Sekunden aus, wenn auch @SequenceNo auf Null überprüft werden muss. – CashCow

+0

Ich sehe, so es nur für Timestamp überprüfen, wenn die @ SequenceNo null ist. Ich habe die Abfrage aktualisiert. –

+0

Ja, das funktioniert. Ich bin nicht 100% zufrieden damit, weil ich wirklich "nicht null" als den ersten Fall möchte und es dann etwas Wahres oder Falsches zurückgibt, abhängig von der zweiten Bedingung. – CashCow

1

Ihr Code sieht wie SQL Server aus (obwohl dies für die Antwort keinen Unterschied macht). Im Allgemeinen ist es am besten, CASE Ausdrücke aus WHERE Klauseln zu verlassen und nur Booleschen Logik:

select t.* 
from MyTable t 
where (@SequenceNo is not null and SequenceNo > @SequenceNo) or 
     (@SequenceNo is null and Timestamp > @Timestamp); 

Da NULL Werte alle Vergleiche scheitern, können Sie dies vereinfachen:

select t.* 
from MyTable t 
where (SequenceNo > @SequenceNo) or 
     (@SequenceNo is null and Timestamp > @Timestamp); 

Und, falls Sie in beiden Werte übergeben wollen und Filterung, vielleicht ist dies nützlich:

select t.* 
from MyTable t 
where (SequenceNo > @SequenceNo or @SequenceNo is null) and 
     (Timestamp > @Timestamp or @Timestamp is null); 

Es ist nicht die gleiche Logik, aber möglicherweise was Sie wollen.

+0

Die letzte kann nützlich sein, aber natürlich nicht die gleichen wie die anderen beiden in allen Fällen. – CashCow

+0

Das ist wahrscheinlich gut genug für das, was ich brauche. In der realen Abfrage gibt es mehr Logik in der Auswahl, d. H. Ein paar Joins, so dass ich keine 2 Prozeduren möchte. – CashCow

0

Use-Case-Statement in folgendem Format:

DECLARE proc dbo.MyProc(@SequenceNo int, @Timestamp datetime) as 
BEGIN 
    SELECT * FROM MyTable 
    WHERE SequenceNo = CASE WHEN (@SequenceNo IS NOT NULL OR SequenceNo > 
     @SequenceNo) THEN @SequenceNo ELSE SequenceNo END 
     AND Timestamp = CASE WHEN @SequenceNo IS NULL AND Timestamp > 
     @Timestamp THEN @Timestamp ELSE Timestamp END 
END 
0

Verwenden der dynamischen Abfrage wie folgt

CREATE PROCEDURE MyProc 
 
( 
 
    @SequenceNo int, @Timestamp datetime 
 
) 
 
AS 
 
BEGIN 
 
DECLARE @SQL Nvarchar(max) 
 
SELECT \t @SQL = N'select * from MyTable where' 
 

 
IF @SequenceNo IS NOT NULL 
 
BEGIN 
 
    SELECT @SQL = @SQL + N' SequenceNo > @SequenceNo'; 
 
END 
 
ELSE 
 
    BEGIN 
 
    SELECT @SQL = @SQL + N' Timestamp > @Timestamp'; 
 
    END 
 

 
EXEC(@SQL) 
 
END

Verwandte Themen