SQL server, Konvertieren eines Auswahlmechanismus von "und" in "oder"

Ich habe ein webbasiertes Programm, das einige datasätze aus einer database mit einer Checkboxliste auswählt. (meine Checkbox-list sendet Parameter an eine gespeicherte Prozedur und ich verwende das Ergebnis der gespeicherten Prozedur).

Hier, wie meine Checkbox-list aussieht

Overflow [] (sends param1) Open Records [] (sends param2) Records with 4 groups [] (sends param3) 

Hier, wie meine gespeicherte Prozedur aussieht,

 SELECT * FROM myRecordsTable WHERE (Overflow LIKE '%O%' OR @param1= 'No') AND (OpenClose= 'Open' OR @param2= 'No') AND (4orMore = '4orMore' OR @param3 = 'No') 

So wie Sie sehen können, funktioniert mein Kontrollkästchen Werke wie "Und" Prozedur, mit anderen Worten, wenn ich Overflow und Open datasätze in meiner Checkboxliste überprüfe, wird meine gespeicherte Prozedur zurückkehren ( Open Records, die Overflow hat )

Was ich gerne mache, ist, dass meine Checkbox-list wie "Or" funktionieren möchte, also möchte ich in der Lage sein zu bekommen ( Open records "ODER" datasätze, die Overflow hat )

Wichtig PS: Ich kann nicht zwei gespeicherte Prozeduren (1 für OR und 1 für AND) haben, da meine Prozeduren nicht so kurz sind wie das obige Beispiel, denn wenn ich einmal etwas in einer Prozedur ändere, muss ich genau die gleichen Änderungen vornehmen das zweite und das ist nicht gut codiert.

Wichtige PS2: Ich möchte nicht die Struktur der gespeicherten Prozedur verderben. Ich möchte meine gespeicherte Prozedur als "AND" oder "ODER" verwenden, wann immer ich will (mit einem anderen Parameter vielleicht), und die Art, wie ich versuchte, dies zu tun war mit dynamischen sql wie in der Link unten

SQL server, Kann ein T-SQL Operator wie eine Variable verwendet werden? Oder etwas ähnliches

aber ich konnte es nicht schaffen, es zu lösen.

Danke für hilfe

Edit: Hier gebe ich ein Beispiel, um das Problem deutlicher zu zeigen

Unter Code, wird nichts in der Checkboxliste ausgewählt, gibt 42703 (Remember this number) Zeilen zurück

 declare @op varchar(3) set @op = 'AND' declare @query nvarchar(4000) set @query = ' SELECT ASIM, SonGrup, DortUzeri FROM CacheOPERASYONELRawKayitlar WHERE ' set @query = @query + '(ASIM LIKE ''%S%'' OR ''No''=''No'') '+@op+' ' set @query = @query + '(SonGrup LIKE ''Son Grup'' OR ''No''=''No'') '+@op+' ' set @query = @query + '(DortUzeri LIKE ''Dört ve Üzeri'' OR ''No''=''No'') ' exec(@query) 

Unter Code ist ASIM ausgewählt, liefert 9349 Zeilen

 declare @op varchar(3) set @op = 'AND' declare @query nvarchar(4000) set @query = ' SELECT ASIM, SonGrup, DortUzeri FROM CacheOPERASYONELRawKayitlar WHERE ' set @query = @query + '(ASIM LIKE ''%S%'' OR ''Yes''=''No'') '+@op+' ' set @query = @query + '(SonGrup LIKE ''Son Grup'' OR ''No''=''No'') '+@op+' ' set @query = @query + '(DortUzeri LIKE ''Dört ve Üzeri'' OR ''No''=''No'') ' exec(@query) 

Ich gebe den gleichen Code nicht mehr, denn die Logik ist gleich, das "Nein" wird in "Ja", wenn die Checkbox-list ausgewählt ist, und dies ist die Struktur des Codes.

ASIM und SonGrup ausgewählt ist die Rückgabe von 5885 Zeilen ASIM und SonGrup und DortUzeri ausgewählt wird, liefert 1385 Zeilen

Der obige Code funktioniert einwandfrei mit AND, also wenn ich ODER Operator verwenden möchte , sollte ich das Ergebnis 37696 bekommen , welches das Ergebnis des untenstehenden Codes ist

 SELECT ASIM, SonGrup, DortUzeri FROM CacheOPERASYONELRawKayitlar WHERE ASIM LIKE '%S%' OR SonGrup LIKE 'Son Grup' OR DortUzeri LIKE 'Dört ve Üzeri' 

Also habe ich den Code mit OR-Operator ausgeführt, wo die drei Checkbox- listnkomponenten ausgewählt sind, der Code ist unten und es gibt 37696 zurück , was korrekt ist.

 declare @op varchar(3) set @op = 'OR' declare @query nvarchar(4000) set @query = ' SELECT ASIM, SonGrup, DortUzeri FROM CacheOPERASYONELRawKayitlar WHERE ' set @query = @query + '(ASIM LIKE ''%S%'' OR ''Yes''=''No'') '+@op+' ' set @query = @query + '(SonGrup LIKE ''Son Grup'' OR ''Yes''=''No'') '+@op+' ' set @query = @query + '(DortUzeri LIKE ''Dört ve Üzeri'' OR ''Yes''=''No'') ' exec(@query) 

Das Problem entsteht, wenn eine der Checkliste Komponenten nicht überprüft wird, hier ist die 3. Komponente ist nicht überprüft Version des Codes,

 declare @op varchar(3) set @op = 'OR' declare @query nvarchar(4000) set @query = ' SELECT ASIM, SonGrup, DortUzeri FROM CacheOPERASYONELRawKayitlar WHERE ' set @query = @query + '(ASIM LIKE ''%S%'' OR ''Yes''=''No'') '+@op+' ' set @query = @query + '(SonGrup LIKE ''Son Grup'' OR ''Yes''=''No'') '+@op+' ' set @query = @query + '(DortUzeri LIKE ''Dört ve Üzeri'' OR ''No''=''No'') ' exec(@query) 

Der obige Code sollte 34613 zurückgegeben haben, den ich mit folgendem gefunden habe

 SELECT ASIM, SonGrup, DortUzeri FROM CacheOPERASYONELRawKayitlar WHERE ASIM LIKE '%S%' OR SonGrup LIKE 'Son Grup' 

Allerdings gibt es 42703 (die Nummer, die ich wollte, dass Sie sich erinnern, verursacht wegen '' Nein '' = '' Nein ''), das ist, wo mein Problem entsteht. Hier konnte ich die Lösung nicht finden.

Sie sollten dynamische sql verwenden – sowie die Syntax ist einfacher auf das Auge wird es auch geben Sie Ihre Anfrage eine bessere Chance auf die Durchführung.

Wenn Sie können, dann würde ich wahrscheinlich das dynamische sql in Ihrer Anwendung anstatt in der gespeicherten Prozedur konstruieren, aber wenn Sie wirklich eine gespeicherte Prozedur aufrufen müssen, dann funktioniert das auch:

Haftungsausschluss: Ich schreibe normalerweise niemals dynamisches SQL in einer gespeicherten Prozedur, und ich habe auch keinen SQL-server auf diesem Rechner installiert, um sicherzustellen, dass die folgenden Arbeiten funktionieren, aber hoffentlich sollte dies eine Hilfe sein:

 declare @op varchar(3) IF @operator = "AND" set @op = "AND" ELSE set @op = "OR" declare @query varchar(max) set @query = "select * from myRecordsTable WHERE" + IF @param1 <> "No" set @query = @query + " Overflow LIKE '%O%' " + @op IF @param2 <> ' No' set @query = " OpenClose = 'Open' " + @op IF @operator = "AND" set @query = @query + " 1=1" IF @operator = "OR" set @query = @query + " 1=0" exec(@query) 

Wichtige zu beachtende Teile:

  • Ich @operator den Wert von @operator explizit zu vermeiden SQL-Injektion (nie Vertrauen Ihrem Anrufer)
  • Ich benutze 1=1 und 1=0 , um komplizierte Logik mit Operatoren zu vermeiden, weil ich nicht weiß, welche meiner Bedingungen die erste oder die letzte ist. Der SQL-server-Optimierer optimiert diesen path als Tautologie frühzeitig im Optimierungsprozess.