mssql4me
Goto Top

Verwendung von Variablen in outer Join

Erst seit kurzer Zeit arbeite ich auch mit MS-SQL-Server 2008. Ich bin dabei auf ein Problem gestossen, für das ich bis jetzt keine Lösung finde. Wer kann helfen?

Ich habe hier ein Stück Code aus einer Procedure welches nicht korrekt arbeitet. Es werden keine Daten zurück geliefert, obwohl für das Datum @bildat Records vorhanden sind.

create proc dbo.sp_abc_123
@bildat DateTime = Null
as
if @bildat is Null
set @bildat = DATEADD(dd,-1,DATEADD(mm,DATEDIFF(m,0,getdate()), 0))

select a.feld_1,
b.feld_2,
...
from PRD..USR.TAB_A a
left outer Join PRD..USR.TAB_B b
on ( ( a.key_a1 = b.key_1 ) and ( b.datum = @bildat ) )
where ...
and ...

Kann in der outer Join Bedingung mit Variablen gearbeitet werden?

Grüsse
MSSQL4Me

Content-Key: 136527

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

Ausgedruckt am: 29.03.2024 um 07:03 Uhr

Mitglied: 76109
76109 22.02.2010 um 10:10:08 Uhr
Goto Top
Hallo mssql4me!

Also, dass kann schonmal nicht funktionieren:
DATEADD(dd,-1,DATEADD(mm,DATEDIFF(m,0,getdate()), 0))

Müsste wohl eher in dieser Richtung lauten (Intervalle als Text)
set @bildat = DATEADD("d",-1,DATEADD("m",DATEDIFF("m",0,getdate()), 0))

Gruß Dieter
Mitglied: mssql4me
mssql4me 22.02.2010 um 11:09:59 Uhr
Goto Top
Hallo Dieter

herzlichen Dank für Deine Antwort. Ich hab's ausprobiert - aber leider funktioniert es so immer noch nicht - egal ob ich bei DATEADD (datepart , number, date ) die "datepart" Argument mit oder ohne " " angebe.

Weiter hab ich noch versucht:
...
left outer Join PRD..USR.TAB_B b
on ( ( a.key_a1 = b.key_1 ) and ( b.datum = '2010-01-31' ) )
where ...

so funktioniert's - d.h ich bekomme so alle records - nur kann ich das Datum in der Procedure nicht fest einbauen, daher die Variable @bildat

Grüsse
MSSQL4Me
Mitglied: MadMax
MadMax 22.02.2010 um 12:30:04 Uhr
Goto Top
Hallo MSSQL4Me,

mit Deinem Codeschnippsel ist erst mal alles in Ordnung, Variablen kann man da auch verwenden.

Es kann also eigentlich nur die Verknüpfung über key_1 sein oder aber, Du hast in Deinen Datumsfeldern nicht nur das Datum, sondern auch Zeiten stehen. Wenn "... on ( ( a.key_a1 = b.key_1 ) and ( b.datum = '2010-01-31' ) ) ..." Ergebnisse liefert, dann sollte die Prozedur auch Ergebnisse liefern, wenn Du sie ohne Parameter bzw. mit @bildat = null aufrufst.

Ersetz doch mal
if @BilDat is Null
set @BilDat = DATEADD(dd,-1,DATEADD(mm,DATEDIFF(m,0,getdate()), 0))
mit
if @BilDat is Null
set @BilDat = DATEADD(d,-1,DATEADD(m,DATEDIFF(m,0,getdate()), 0))
else
set @BilDat = DATEADD(d,DATEDIFF(d,0,@BilDat), 0))

Dann wären schonmal aus @bildat die Zeiten raus, ggf. müßte das auch noch mit b.Datum passieren.

Edit: das war natürlich Müll, da wär @bildat ja komplett verändert worden, habs gerade nochmal korrigiert.

Gruß, Mad Max
Mitglied: 76109
76109 22.02.2010 um 12:48:46 Uhr
Goto Top
Hallo mssql4me!

Mit den Stringzeichen habe ich mich wohl geirrt, aber ich habe mal Deine Date-Funktion in Excel getestet und mit
x = DateAdd("d", -1, DateAdd("m", DateDiff("m", 0, Date), 0))
bekomme ich als Ergebnis den 27.02.2010. Von daher dürfte es nicht funktionieren

Wobei das Ergebnis z.B. mit
x = DateAdd("d", -1, Date)
der 21.02.2010 wäre

Gruß Dieter
Mitglied: mssql4me
mssql4me 22.02.2010 um 16:15:10 Uhr
Goto Top
Hallo Mad Max

auch dir Danke für deine Antwort, aber leider sind auch mit Deinen Angaben immer noch keine Records da. Die Verknüpfung über key_1 ist korrekt, das habe ich schon untersucht. Ich habe (wie Du auch) den Verdacht dass mit @bildat nicht '2010-01-31' daher kommt... aber ich habe keine Ahnung, wie ich das verifizieren kann. Ein Versuch mit:

print @bildat

brachte auch keine weiteren Ideen, ausser dass ich noch mehr verwirrt war, da das Datum in einem anderen Format angezeigt wird???

Grüsse MSSQL4Me
Mitglied: 76109
76109 22.02.2010 um 17:06:45 Uhr
Goto Top
Hallo mssql4me!

Beispiel für den 31.01.2010 in Excel (in SQL entsprechend anpassen)

Der letzte Tag des Vormonats ließe sich, falls vorhanden mit Dateserial() in Kombination mit DateAdd ermitteln
x = DateAdd("d", -1, DateSerial(Year(Date), Month(Date), 1))
Ohne DateSerial dann so:
x = DateAdd("d", -1, "01" & "-" & Month(Date) & "-" & Year(Date))
Wobei DateSerial den aktuellen Monat mit dem 1. Tag bestimmt und DateAdd -1 Tag den letzten Tag des Vormonats.


Gruß Dieter
Mitglied: MadMax
MadMax 22.02.2010 um 21:34:07 Uhr
Goto Top
Moin MSSQL4Me,

DATEADD(dd,-1,DATEADD(mm,DATEDIFF(m,0,getdate()), 0)) bringt, zumindest auf dem SQL Server 2005, derzeit den 31.01.2010. Deswegen die Frage, ob Du die Prozedur ohne Parameter probiert hast, denn dann müßte das Datum stimmen. Wenn "print @bildat " aber kein gescheites Datum gebracht hat, bzw. ein seltsames Format, dann frage ich mich, wie Euer SQL Server konfiguriert ist, oder was Du für Variablen verwendest. Probier mal "print convert (varchar (30), @bildat, 120)", wenn Dir das nicht etwas in der Form "2010-01-31 00:00:00" zurückgibt, dann stimmt was nicht. Vielleicht kannst Du ja auch mal hier reinschreiben, was Dein print zurückgeliefert hat.

Achja, was passiert eigentlich, wenn Du den 31.01.2010 nicht explizit in der Abfrage verwendest, aber explizit @bildat zuweist? Was passiert, wenn Du das "if @bildat is Null" wegläßt und immer dieses berechnete Datum zuweist?

Gruß, Mad Max
Mitglied: mssql4me
mssql4me 23.02.2010 um 12:08:02 Uhr
Goto Top
Hallo Mad Max

vielen Dank für deine Zeilen, da stecken ja ganz viele Ideen drin, ich versuch mal alles zu beantworten:

Die Bestimmung des Datums für @bildat bringt auch bei mir (auch unter SQL Server 2005) jeweils das Monatsende des Vormonats zurück -> das ist auch so beabsichtigt.

Der print @bildat bringt aktuell Jan 31 2010 12:00AM zurück. Definiert habe ich für @bildat Datetime (habe auch schon mit smalldatetime versucht)

Wenn ich deine print Anweisung einbaue, also print convert (varchar (30), @bildat, 120) erhalte ich "2010-01-31 00:00:00"
Auch schon probiert habe ich print convert (varchar (10), @bildat, 120) dann wird nur das Datum ohne Zeit geliefert.


Die Procedur wird jeweils immer mit 2 - 3 Variante getestet, also so:

exec dbo.sp_abc_123 Null
exec dbo.sp_abc_123 '2010-01-31'
oder auch
exec dbo.sp_abc_123 '2009-12-31'

Meine Absicht ist - aber das habt Ihr sicher alle längst erkannt face-smile - mit "Null" das Datum automatisch zu erhalten (Monatsletzter Vormonat) aber auch die Möglichkeit zu haben, über ein altes Monatsende die Daten abzurufen. Die Procedure wird über einen Job mit Schedule jeweils am 1.Tag des Monats gestartet...

Deine letzten Angaben habe ich noch nicht getestet, werde ich aber noch angehen... ich melde mich sicherlich nochmal, um die Resultate durchzugeben.

Herzlichen Dank schon mal, und bis bald

Grüsse MSSQL4Me

---
Hallo zusammen

Also die letzten beiden Punkte habe ich jetzt auch noch getestet.

alter proc dbo.sp_abc_123
@bildat DateTime = Null
as
set @bildat = '2010-01-31 00:00:00'
-- set @bildat = '2010-01-31'
-- set @bildat = DATEADD(d,-1,DATEADD(m,DATEDIFF(m,0,getdate()), 0))

print convert(varchar(30), @bildat, 120);
...

bei allen 3 Fällen ist die Ausgabe des print Befehls 2010-01-31 00:00:00

aber es werden keine Records zurückgeliefert.

Grüsse MSSQL4Me