h41msh1c0r
Goto Top

SQL Statement auseinandernehmen Like

Hi@All,

Ziel:
Beim erstellen eines Reports existiert ein Feld in der eine bestimmte OU ausgewählt werden kann.
Wird keine ausgewählt gilt die Auswahl auf alle, ansonsten auf die die ausgewählt wurde.

Problem:
Aktuell bekomme ich auch Rechner aus anderen OUs die garnicht in der Schnittmenge enthalten sein dürften.

and [OU] like case when @Parameter_OU = 'ALL' then '%' Else ('%' + @Parameter_OU + '%') end  

Wenn ich das Statement richtig lese wird:
- wenn ALL ausgewählt wurde alle OUs genommen die in der Liste sind
- wenn direkt eine OU ausgewählt worden ist, wird diese genommen

Oder habe ich da was gänzlich missverstanden?

Gruß

Content-ID: 315129

Url: https://administrator.de/contentid/315129

Ausgedruckt am: 14.11.2024 um 17:11 Uhr

MadMax
MadMax 13.09.2016 um 12:41:06 Uhr
Goto Top
Hallo H41mSh1C0R,

das stimmt so nicht ganz, durch das like werden alle die geholt, die @parameter_ou enthalten.
D.h. wenn Du nach 'xyz' suchst, bekommst Du auch 'abxyz' und 'xyzz'.

Wenn nur exakt das gesuchte zurückkommen soll, dann müßte die Abfrage lauten:
and [OU] = case when @Parameter_OU = 'ALL' then [OU] Else @Parameter_OU end  

Außerdem hast Du nicht die komplette Where-Bedingung hier reingeschrieben. Wenn da noch irgendwo ein "or" drin ist, dann kann dabei noch sonstwas dazugelesen werden.

Gruß, Mad Max
em-pie
em-pie 13.09.2016 um 12:46:05 Uhr
Goto Top
Moin,

Von der Syntax her scheint der Schnippsel ja richtig zu sein.

Was kommt denn dabei rum, wenn du dein "CASE When" mit in den Select-Bereich einbindest?
Also

Select
 -- prüfen, ob die CASE-Clause überhaupt greift
  case 
    when @Parameter_OU = 'ALL' then 'ALLE'   
    Else 'Selektiert'  
  end as "TEST"  
from
 blablabla

Und wie sieht dein Where-Statement in Gänze aus?
Nicht, dass dort irgendwo noch ein OR enthalten ist und dadurch zu deinem o.g. Statement eine alternative Auswahl (ungewollT) dargestellt wird.

Mit mehr Infos könnte man vermutlich etwas mehr Hilfe geben:
  • Welcher SQL-Server? (DB2, MSSQL 2005, Oracle, ...)
  • Was ist in OU enthalten?
  • Was ist in @parameter_ou enthalten
  • Wie lang sind die Felder deklariert?
  • Wie sieht dein gesamten (Where-)Statement aus?


Gruß
em-pie
H41mSh1C0R
H41mSh1C0R 13.09.2016 aktualisiert um 12:53:07 Uhr
Goto Top
Hi Mad Max,

schonmal danke, werd ich ausprobieren.

Sind die "=" notwendig?

Alle Bestandteile/Filter sind mit UND verknüpft und da das die einzige Zeile ist die die OU filtert wird das Problem in dieser Zeile sein.

Gruß

EDIT:
@em-pie
Auch dir danke schonmal.

Immo wird SQL 2008 Express benutzt als DB.

Das gesammte Statement müsste ich abschreiben(immo 16 Zeilen), das ist grad etwas heftig. ^^
Der Select geht über eine Tabelle in der dann gefiltert wird, mitunter auch die OU. Als OU geht z.B. der Standort durch(Köln, Berlin usw. usw.). In Parameter_OU sind quasi die Standorte in einer Dropdown Liste zur Auswahl, so das man den Report nach Standort ausführen kann. =)
MadMax
MadMax 13.09.2016 um 13:16:57 Uhr
Goto Top
Hallo H41mSh1C0R,

was heißt 'Sind die "=" notwendig?'? Irgendeinen Vergleichsoperator brauchst Du. Nach Deiner Anforderung hat sich das '=' richtig angehört face-smile

Gruß, Mad Max
em-pie
em-pie 13.09.2016 um 13:41:36 Uhr
Goto Top
naja Copy&Paste wäre ja auch machbar, zur Not via Textdatei.

Aber weiter im Text.
Der Hinweis von MadMax, dass du die %-Zeichen im Else-Zweig weglassen kannst, ist berechtigt.
Ich hatte gedacht, du wolltest dann, wenn die USer "Köln" auswählen auch OUs wie Neuköln oder Köln-Deutz haben

Ansonsten prüfe mal deine Tabelle, in der die Zurodnung OU = Parameter_OU enthalten ist
nicht, dass da irgendwie Werte doppelt vorkommen:
Parameter_OU | OU
Berlin       | OU-Berlin
Köln         | OU-Kölnln         | OU-Dortmund
Hamburg      | OU-Hamburg


Und das = musst du mitnehmen, wäre, als wolltest du eine Abfrage über Merkmale von fahrzeugen starten:
Zeige alle Fahrzeuge mit Räder 3
Das System wüsste ja ncht, sollen es weniger als drei Räder sein oder exakt 3 Räder oder mehr als 3 Räder
H41mSh1C0R
H41mSh1C0R 13.09.2016 um 14:01:01 Uhr
Goto Top
Copy & Paste ginge nur, wenn beides auf der selben Maschine läuft. Remote komm ich auch nicht dran, ist 100% getrennt. *gg*
Wenn ich anfange hier mit Sticks zu hantieren gibts auch ........ . Keine Chance

Der Select läuft auf einer DB fürs Patchen. In den OU's sind Standorte gegliedert und unter den OUs können noch Bereiche untergliedert sein.

ln
   Bereich 1
   Bereich 2
Berlin
   Bereich 3
   Bereich 4

Wenn nun einer OU Köln auswählt sollen halt alle Rechner einbezogen werden aus Bereich 1 und 2.
Momentan zeigt sich das allerdings so das auch Rechner aus 3 und 4 eingebunden werden.

In der Tabelle gibt es als Spalte OU. Das @parameter_ou ist ein Value in einem Label aus dem Report.

Trotzdem schonmal fettes Danke euch beiden. Ich melde mich.
ice.polar
Lösung ice.polar 13.09.2016 um 14:07:35 Uhr
Goto Top
Hi

ich sehe das anders:
Diese case Statements kann man auflösen, je nachdem die Bedingung erfüllt ist oder nicht.
and [OU] like case when @parameter_ou = 'ALL' then '%' Else ('%' + @parameter_ou + '%') end

das ergibt im Falle dass @parameter_ou = 'ALL' ist:
and [OU] like '%'
Datensätze wo [OU] NULL ist werden dabei nicht ins Resultat übernommen!

falls der Wert in @parameter_ou <> 'ALL' ist (z.B. 'Köln') resultiert folgendes Kriterium:
and [OU] like '%Köln%'

falls der Wert in @parameter_ou = 'Köln, Frankfurt, Berlin' ist, resultiert folgendes Kriterium:
and [OU] like '%Köln, Frankfurt, Berlin%'
was wahrscheinlich nichts schlaues als Resultat gibt!

und falls der Wert in @parameter_ou leer ist (z.B. eine Zeichenkette mit der Länge Null)
and [OU] like '%%')

schliesslich falls @parameter_ou einen undefinierten Zustand hat (in SQL Server nennt man das NULL), dann gibts:
and [OU] LIKE NULL
und damit ist diese ganze Bedingung "ungültig"...

Das sind keine einfachen Bedingungen aber testweise einfach reproduzierbar.
H41mSh1C0R
H41mSh1C0R 13.09.2016 um 14:36:09 Uhr
Goto Top
Hier mal der komplette Teil relevante Teil:
Es gibt 6 unterschiedliche States, das ist der für Parameter_State=1.

declare @crlf char(2)
--declare @Parameter_State int
--set @crlf = char(13) + char(10)
--set @Parameter_State = 1
set @crlf = char(13) + char(10)  

if @Parameter_State = 1 Begin
select convert(nvarchar(500),('KB-Article: ' + KBArticleId + @crlf + 'Security BulletinID: ' +ISNUll([Security BulletinID],'not exists') ) ) AS 'Patch',* from v_PatchMan  
where Status=1 and [Reboot Required]='No'  
  and ComputerID in (@Parameter_Computername)
  and KBArticleId in (@Parameter_Patch)
  and Active in (@Parameter_isActiv)
  and [Reboot Required] in (@Parameter_RebootReq)
  and [OU] like case when @Parameter_OU = 'All' then '%' Else ('%' + @Parameter_OU + '%') end  
  and SUBSTRING(OU,0,CHARINDEX(',',OU)) = ANY (select NAME from PermittedObj(@UserName))  
  and Prima in (@Parameter_Prima)
  and [Severity from Group] in (@Parameter_Severity)
  and Groups like case when @Parameter_Groups = 'All' then '%' Else ('%' +@Parameter_Groups + ',' + '%') End  
  and [Dynamic Groups] like case when @Parameter_DynGroups = 'All' then '%' Else ('%' + @Parameter_DynGroups + ',' + '%') End  
end
MadMax
MadMax 13.09.2016 um 14:38:00 Uhr
Goto Top
Hallo H41mSh1C0R,

der Einwand von ice.polar mit dem NULL-Wert ist grundsätzlich mal richtig, aber dürfte bei Dir nicht das Problem sein, weil das nämlich, wenn es auftreten kann, zu weniger Ergebnissen führt, als zu mehr. Ob [OU] oder @parameter_ou NULL werden können, mußt Du wissen und dann ggf. mit IsNull o.ä. abfangen.

Aber: wenn Du mit dem hier geschriebenen noch nicht Dein Problem gelöst hast, dann wirst Du wohl in den sauren Apfel beißen müssen und den Befehl abschreiben. Dann liegt nämlich das Problem wohl doch woanders und hellsehen kann hier glaube ich keiner. Hab ich zumindest noch nicht mitbekommen face-smile

Jedenfalls behaupte ich mal, wenn Du den Befehl gleich komplett abgeschrieben hättest, wäre Dein Problem wahrscheinlich schon gelöst. Und somit schneller gegangen als dieses ganze hin und her.

Gruß, Mad Max
H41mSh1C0R
H41mSh1C0R 13.09.2016 um 14:40:14 Uhr
Goto Top
Hi Mad Max,

grad 2 Minuten vor deinem Post gepostet. =)

Gruß
em-pie
em-pie 13.09.2016 um 14:52:41 Uhr
Goto Top
Schaut auf den ersten Blick OK aus.


Zitat von @H41mSh1C0R:

Hi Mad Max,

Der Select läuft auf einer DB fürs Patchen. In den OU's sind Standorte gegliedert und unter den OUs können noch Bereiche untergliedert sein.

ln
   Bereich 1
   Bereich 2
Berlin
   Bereich 3
   Bereich 4

Wenn nun einer OU Köln auswählt sollen halt alle Rechner einbezogen werden aus Bereich 1 und 2.
Momentan zeigt sich das allerdings so das auch Rechner aus 3 und 4 eingebunden werden.

In der Tabelle gibt es als Spalte OU. Das @parameter_ou ist ein Value in einem Label aus dem Report.

Wie willst du denn die Subbereiche abfragen?
Also wie sieht das Feld [OU] Inhaltlich aus?
stehen da die Werte wie "OU=Bereich 1, OU=Köln, OU=Regionen, OU=Company, DC=Company, DC=local" ?
H41mSh1C0R
H41mSh1C0R 13.09.2016 um 14:59:37 Uhr
Goto Top
In der DB heißt die Spalte so.

Im Report kann man dort aus der Liste einen oder mehrere Einträge auswählen.

Der Eintrag kann z.B. SCW04P-T7 heißen. In dieser Organisationseinheit stehen dann alle Rechner vom Standort P, Bereich T7.
SCW04P-T8 ist dann der gleiche Standort aber der Bereich T8.

Sprich wird nur SCW04P-T7 ausgewählt sollten auch NUR die Rechner betrachtet werden die der OU zugeordnet sind.
Somit muss in der Auswahlliste dann der Subbereich direkt ausgewählt sein.

Will man beide haben müssen beide ausgewählt werden.

Gruß
ice.polar
ice.polar 13.09.2016 um 15:51:41 Uhr
Goto Top
Hi
und was steht denn da in @parameter_ou wenn "...beide ausgewählt werden..."?
H41mSh1C0R
H41mSh1C0R 13.09.2016 um 16:17:35 Uhr
Goto Top
Hi,

bei allen multiselectfeldern steht dann Wert1,Wert2,Wert3 usw.. Also mit Komma getrennt.
Kann es sein das ggf. zwei ',' fehlen?

Gruß
H41mSh1C0R
H41mSh1C0R 14.09.2016 um 11:25:56 Uhr
Goto Top
Danke auch dir.

in der Spalte stehen z.B. "Köln, Frankfurt, Berlin, München, Bern"

and [OU] like '%Köln, Frankfurt, Berlin%'  

liefert die Schnittmenge bei der die 3 Standorte als Teilstring so vorkommen.

Wählt nun einer "Köln, Berlin, Bern" aus bekommt er nichts zurück da er diesen Teilstring nicht findet.

Steh grad sehr auf dem Schlauch wie ich ihm mitteile das er für jede einzelne Auswahl die Clients hinzufügen soll in die Ergebnismenge.

;(
ice.polar
ice.polar 15.09.2016 um 11:36:20 Uhr
Goto Top
Hi

... und wählt einer "Köln, Berlin, Frankfurt" klappts auch nicht (andere Reihenfolge)...

Ich versteh's noch nicht ganz: hat es in der Tabelle v_PatchMan in der Spalte OU immer exakt eine OU (z.B. 'Berlin') oder stehen da schon alle möglichen (z.B. Köln, Berlin, Bern)? Ist die Reihenfolge da festgelegt oder könnte dann auch Köln, Bern, Berlin stehen?

Im Parameter @parameter_ou soll ja eben eine Auswahl an OU's zur Verarbeitung angegeben werden (z.B. Köln, Frankfurt, Berlin).

Dabei entsteht ein schöner Vergleich (n:n) zwischen v_PatchMan.ou und @parameter_ou.
H41mSh1C0R
H41mSh1C0R 15.09.2016 aktualisiert um 12:14:23 Uhr
Goto Top
Hi,

In dem OU Feld steht der pfad bis zur OU drinnen.

Beispiel: Berlin,Brandenburg,Deutschland

Der Eintrag existiert pro Patch pro Rechner.

Wenn man nun nach OU filtert, sollten alle Einträge im Select bleiben die innerhalb existieren.
Sind mehrere OUs ausgewählt kommen die Einträge aus der anderen OU hinzu.

In der Parameterliste(Checkbox) für die OU sind z.B. die Städte alle gelistet und man kann die Städte auswählen.

Ich sitze gerade dran wie ich den Eintrag zerlegt bekomme und in einer Schleife die ausgewählten Parameter abgleiche.
ice.polar
ice.polar 15.09.2016 um 15:23:32 Uhr
Goto Top
Hi,

Ich versteh' so langsam. In der Datenbank-Tabelle ist pro Datensatz eine einzige OU (inkl.Pfad, daher die Selektion mit Like).
In der Parameterliste (@Parameter_OU) kriegst Du eine Komma-separierte Liste: Eigentlich eine lange Zeichenkette.

Falls diese alle eine fixe Länge hätten, könnte man das direkt in SQL lösen. Fixe Länge bedeutet dass immer z.B. 20 Zeichen zwischen den Kommas sind ("Berlin ,Dortmund ,Ravensburg ").

Andernfalls ist eine procedurale Schlaufe ein Lösungsweg.
em-pie
Lösung em-pie 15.09.2016 um 15:40:52 Uhr
Goto Top
Jetzt wird es auch für mich etwas transparenter face-smile

Habe gerade mal kurz gegoogelt und diesen Post (in einem anderen Forum) gefunden:
http://stackoverflow.com/questions/5493510/turning-a-comma-separated-st ...

Hier will der TO zwar das Problem lösen, dass er in einem Feld einer Bestandstabelle kommaseparierte Werte hat, aber das müsste sicherlich auch für dein @parameter_ou genauso funktionieren.

Schaue dir insbesondere mal den Post von Jayvee (ca. Anfang der 2. Hälfte) an.

Bilde vor deinem eigentlichen Statement eine temporäre Tabelle, welche alle relevanten Daten beinhaltet, und zwar nicht mehr kommasepariert und dann joinst du die mit deinem eigentlichen Statement.
Abschließend die Tabelle wieder leeren/ plattmachen.

Stichwort hier: Table Variable:
https://msdn.microsoft.com/de-de/library/ms175010.aspx

Habe das alles selbst aber nicht getestet noch nie verwenden müssen ;)
H41mSh1C0R
H41mSh1C0R 15.09.2016 um 16:16:20 Uhr
Goto Top
Trotzdem schonmal danke euch beiden. Ich schau mir das morgen früh an.

*mir glüht der Kopf, da geht nix mehr*

=)