hh2000
-
Gesamte Inhalte
550 -
Registriert seit
-
Letzter Besuch
Beiträge erstellt von hh2000
-
-
Moin,
ist das ein "Instead of" oder "After" Trigger?
Biite immer bedenken, das beim Einfügen kein, ein oder mehrere Datensätze möglich sind. Das muss der Trigger
verarbeiten können. Unbedingt den Trigger auf diese Fälle prüfen.
> SELECT @Variable = Zelle FROM inserted
Was passiert mit @Variable, wenn du mehr als einen Datensatz verarbeitest?
Schöner ware etwas wie:
IF EXISTS ( SELECT * FROM inserted Where ....) BEGIN ... Tut hier was END
Du kannst zum prüfen auch inserted mit anderen Tabellen JOINen, um dann weitere Aktionen durchzuführen.
> beim eingefügten Datensatz sind einige Zellen mit NULL
Hast Du evtl. noch andere Befehle im Trigger die die Tabelle inserted manipulieren ?
Ob der xp_cmdshell hier evtl. noch andere Nebenwirkungen bei bestimmten Bedingungen hat, weiß ich leider nicht.
Gruß Kai
-
Das sieht von der Struktur her schonmal gut aus.
Nur als Tipp:
- Betrachte jedes SELECT Statement für sich und bewerte das Ergebenis
- kontrolliere nochmal den JOIN (evtl. Copy-Paste Fehler)
- kommen die Daten aus der jeweils richtigen Spalte
- kontrolliere den WHERE String, oben hast du noch von 'EVARFFOLIENNUMMER%' gesprochen, der taucht hier aber nicht mehr auf.
Gruß Kai
-
Moin,
z.B. eine zweite Abfrage (mit anderem JOIN) mit gleichem Spaltenlayout machen und beide Abfragen dann mit UNION (siehe Onlinehilfe) verknüpfen.
Gruß Kai
-
... die im Feld "KEYIPAR1 mit "EVARFFOLIENNUMMER%" als Schlüssel haben? ...
einfach ein
OR KEYIPAR1 like 'EVARFFOLIENNUMMER%'
anhängen (OR, AND, siehe Onlinehilfe):
join tbl_par on tbl_par.parlfd2 = tbl_vbs.VBSFOLET where KEYIPAR1 like 'EVARFFOLIENETIKET%' OR KEYIPAR1 like 'EVARFFOLIENNUMMER%'
Sollte allerdings 'EVARFFOLIENNUMMER%' eine feste Zeichenkette sein, so solltest Du statt "like" lieber "=" benutzen ("like" funktioniert hier aber auch).
Gruß Kai
-
Moin,
als Anregung, die Abfrage
SELECT TOP 1 ArtikelNr, Preis FROM T_Tabelle ORDER BY Datum DESC WHERE Artikel = 4711
ergibt den gesuchten aktuellen Preis für _einen_ Artikel.
Das kann man z.B. in eine korrelierende Unterabfrage einbauen:
SELECT ArtikelNr, ( SELECT TOP 1 Preis FROM T_Tabelle B ORDER BY Datum DESC WHERE B.ArtikelNr = A.ArtikelNr ) AS AktuellerPreis FROM T_Tabelle A
Evtl. noch GROUP BY je nach Bedarf
Gruß Kai -
Moin,
anderer Vorschlag:
-- andere Datentypen
DECLARE @Jahr SMALLINT
DECLARE @Monat TINYINT
SET @Jahr = 2014
SET @Monat = 12CAST('01.' + STR(@Monat) + '.' + STR(@Jahr) AS DATETIME)
Gruß Kai
-
Moin,
das wären m.E. die verschiedenen Ansätze zu Deinen Fragen:
-- Kunden die gar nicht in Tabelle 2 (T2) enthalten sind:
SELECT Tabelle1.*
FROM Tabelle1
WHERE Tabelle1.Kunde NOT IN (
SELECT Kunde
FROM Tabelle2
)
-- Kunden die keine Artikel in Tabelle 2 (T2) haben:
SELECT Tabelle1.*
FROM Tabelle1
WHERE Tabelle1.Artikel NOT IN (
SELECT Artikel
FROM Tabelle2
WHERE Tabelle1.Kunde = Tabelle2.Kunde
)
-- Kunden die sowohl in T1 als auch in T2 Artikel die gleichen Artikel haben
SELECT Tabelle1.*
FROM Tabelle1
INNER JOIN Tabelle2
ON Tabelle1.Kunde = Tabelle2.Kunde
AND Tabelle1.Artikel = Tabelle2.Artikel
ggf. doppelte Datensätze / Sortierung sind nicht berücksichtigt.
Gruß Kai
-
Moin,
hat Deine Tabelle einen eindeutigen Schlüssel oder eine Spalte von Typ timestamp ?
Gruß Kai
-
Moin,
ohne auf das Subselect einzugehen, müsste ein weiteres GROUP BY ausreichen:
SELECT System_Typ, count(*) as System_Zugriffe_Monat_NB FROM( SELECT SUBSTRING([Ev_Station],1,2) as System_Typ FROM [TEST].[dbo].[EVENTHISTORY] WHERE CAST(substring(CONVERT(varchar(10),[Ev_Time],101),1,2) as numeric) = @paraMonat and cast(substring(CONVERT(varchar(10),[Ev_Time],101),7,4) as numeric) = @paraJahr and Ev_User !='Unbestimmter Benutzer' and Ev_User != 'Guest' --and SUBSTRING([Ev_Station],1,2)='NB' group by [Ev_User],[Ev_Station],SUBSTRING([Ev_Station],1,2) ) z GROUP BY System_Typ
Gruß Kai
PS: Funktionieren mit der Spalte "Ev_Time" keine Datumsfunktionen?
-
Moin,
ich würde unter SQL immer versuchen _keine_ While-Schleifen oder sehr viele Subselects einzusetzen.
Zerlege das Problem in kleine Schritte und schau dir jeweils die Zwischenergebnisse an:
- Annahme: die Zählerstande sind aufsteigend, das Feld Datum enthält das Datum zum Messwert.
1 .View mit den Monatszählerständen (hier nur ein Zähler):
SELECT YEAR([Datum]) as Jahr, MONTH([Datum]) as Monat, MAX([Zaehler_1K1_1]) AS AktuellerMonat FROM [SKEMS-HST-POWER].[dbo].[EnergieMonat] AS AktMonat GROUP BY YEAR([Datum]), MONTH([Datum])
2. "Hilfs"-View mit den Vormonatswerten in der aktuellen Monatszeile.
Das DATEADD dient nur dazu, die Monat- / Jahresspalten anders darzustellen (Monat + 1):
SELECT YEAR(DATEADD(mm, 1, [Datum]) as Jahr, MONTH(DATEADD(mm, 1, [Datum]) as Monat, MAX([Zaehler_1K1_1]) FROM [SKEMS-HST-POWER].[dbo].[EnergieMonat] AS VorMonat GROUP BY YEAR(DATEADD(mm, 1, [Datum]), MONTH(DATEADD(mm, 1, [Datum])
3. Hinzufügen zweier Hilfsspalten:
SELECT YEAR([Datum]) as Jahr, MONTH([Datum]) as Monat, MAX([Zaehler_1K1_1]) AS AktuellerMonat, 0 AS Vormonat FROM [SKEMS-HST-POWER].[dbo].[EnergieMonat] AS AktMonat GROUP BY YEAR([Datum]), MONTH([Datum]) SELECT YEAR(DATEADD(mm, 1, [Datum]) as Jahr, MONTH(DATEADD(mm, 1, [Datum]) as Monat, 0, MAX([Zaehler_1K1_1]) FROM [SKEMS-HST-POWER].[dbo].[EnergieMonat] AS VorMonat GROUP BY YEAR(DATEADD(mm, 1, [Datum]), MONTH(DATEADD(mm, 1, [Datum])
Beide Tabelle haben nun das gleiche Format:
Jahr, Monat, AktuellerMonat, Vormonat
Mittels UNION ALL beide Views zusammenfügen und per erneutem GROUP BY
gruppieren. So würde dann der fertige View aussehen:
SELECT Jahr, Monat, SUM(AktuellerMonat), SUM(Vormonat), SUM(AktuellerMonat) - SUM(Vormonat) AS Differenz FROM ( SELECT YEAR([Datum]) as Jahr, MONTH([Datum]) as Monat, MAX([Zaehler_1K1_1]) AS AktuellerMonat, 0 AS Vormonat FROM [SKEMS-HST-POWER].[dbo].[EnergieMonat] AS AktMonat GROUP BY YEAR([Datum]), MONTH([Datum]) UNION ALL SELECT YEAR(DATEADD(mm, 1, [Datum]) as Jahr, MONTH(DATEADD(mm, 1, [Datum]) as Monat, 0, MAX([Zaehler_1K1_1]) FROM [SKEMS-HST-POWER].[dbo].[EnergieMonat] AS VorMonat GROUP BY YEAR(DATEADD(mm, 1, [Datum]), MONTH(DATEADD(mm, 1, [Datum]) ) a GROUP BY Jahr, Monat
Für weitere Zähler die Zeilen "MAX([Zaehler_1K1_1]) AS AktuellerMonat, 0 AS Vormonat" und"0, MAX([Zaehler_1K1_1])" kopieren und die Aliasnamen anpassen.
Gruß Kai
-
Moin,
Cursor sollten nur für Probleme genutzt werden, die nicht mit "normalen" SQL gelöst werden
können (mengenbasiert <> zeilenorientiert).
Korrekte Rechte auf den verschiedenen Datenbanken vorausgesetzt, könnte das so aussehen (Vollqualifizierter Bezeichner):
SELECT * FROM DB1.dbo.stammdaten UNION ALL SELECT * FROM DB2.dbo.stammdaten UNION ALL SELECT * FROM DB3.dbo.stammdaten ...
siehe auch SQL-Onlinehilfe "Bezeichner"
Gruß Kai
-
Moin,
mit einem Sub-SELECT funktioniert es:SELECT ID FROM Tabelle WHERE Zwischendatensatz IN ( SELECT Zwischendatensatz FROM Tabelle WHERE Enddatensatz = 66 )
Das ist jedoch nur ein Teil-Ergebnis der Gesamtlösung, genaugenommen nur die Antwort auf Deine letzte Frage.
Gruß Kai
-
Moin,
das könnte so aussehen:
SELECT tab_alles.fil as Filiale tab_alles.name as Sachbearbeiter COUNT (tab_alles.name) as Anzahl_pro_Sachbearbeiter SUM (tab_alles.pos) as Positionen_pro_Sachbearbeiter DATEPART (Month, tab_alles.datum) as Monat FROM ( SELECT tab1.fil, tab1.name, tab1.pos, tab1.datum WHERE tab1.datum BETWEEN ('01-01-2013') AND ('31-12-2013') UNION ALL SELECT tab2.fil, tab2.name, tab2.pos, tab2.datum WHERE tab2.datum BETWEEN ('01-01-2013') AND ('31-12-2013') ) tab_alles GROUP BY DATEPART(Month,tab_alles.datum), tab_alles.fil, tab_alles.name
Gruß Kai
-
Moin,
wie schon gesagt, mit einem Sub-SELECT funktioniert es:
SELECT * FROM Tabelle WHERE Auftrag IN ( SELECT Auftrag FROM Tabelle WHERE Position IS NULL )
Gruß Kai
-
Moin,
- ja, du kannst mehrere Insert Trigger in einer Tabelle installieren (Auswirkung, Nebenwirkung?).
- ja, du kannst mittels Trigger alte Angebote updaten
Aber,
- du kannst ganz schnell (schneller als einem lieb ist) die Daten der Tabelle komplett schrotten!
- bei einem Strukturupdate funktioniert das ganze nicht mehr
Ich empfehle hier Lektüre oder Onlinehilfe bezüglich Trigger mit seinen
Hilfstabellen INSERTED und DELETED, das lohnt sich wirklich.
So schön Trigger auch sind (ich benutze sie auch), ist ein genaues Wissen inkl. Tests
nötig, z.B. beim Insert-Trigger das testen von
einfügen von keinem, einem und mehreren Datensätzen.
Noch als Warnung, bei einem schlechten Test des Trigges fällt Dir evtl. ein Fehler erst später auf, weil dann eine
Bedingung eintritt die du nicht bedacht hast und der Trigger mehr geändert hat, als er sollte. Ergebnis: Tabellendaten sind Schrott
Gruß Kai
-
Moin,
wenn der Fehler auftritt, arbeitet die Fibu immer noch korrekt und alle anderen Access-User können auch noch arbeiten oder "hängt"
dann jeder Access-User, bzw. Applikation ?
Gruß Kai
-
Moin,
der beste Weg wäre wohl, wie schon hier vorgeschlagen wurde, eine Produktionsnummer mit in die Tabelle aufzunehmen.
Die andere Lösung (nicht so schön) könnte so aussehen:
Vorausetzungen:
- ID ist chronologisch
- eine Produktion ist immer zusammenhängend in der Tabelle vorhanden
- es wird nur der aktuelle Type ermittelt
SELECT SUM(Anzahl)
WHERE ID > (
SELECT MAX(ID) -- letzte, höchste ID aller anderen Types
FROM Tabelle
WHERE Type NOT IN (SELECT TOP 1 Type -- aktueller Type = letzte Zeile in der Tabelle
FROM Tabelle
ORDER BY ID DESC
)
)Der innerste Select (Ergebnis eine Zeile) ermittelt den aktuellen Type. Daraufhin wird die höchste ID aller
anderen Types ermittelt (deine Grenze).
Dann noch die Werte aller größeren ID summieren.
Ist nicht getestet, gerade was die Laufzeit betrifft.
Gruß Kai
-
Moin,
wie Dukel schon schrieb, gibt es min. 2 Varianten:
1. Mit DatumVon und DatumBis in der Preistabelle
- es muss bei der Eingabe drauf geachtet werden, dass keine "Lücken" im Datum entstehen
- einfachere Abfrage
2. ÄnderungsDatum
- einfacheres Eingeben
- kompliziertere Abfrage
Beispiel für Nr. 2:
T_Artikel
--------------------
[ArtikelID] Primary Key
[ArtikeName]
T_Preis---------------------
[PreisID] Primary Key
[ArtikelID] Foreign Key, verweist auf ArtikelID in Tabelle T_Artikel
[GueltigAb]
[Preis]
Abfrage zum ermitteln des Preises zum Zeitpunkt XX (könnte auch in der Zukunft liegen):
SELECT a.ArtikelID, a.ArtikelName,
(SELECT TOP 1 p.Preis
FROM T_Preis p
WHERE a.ArtikelID = p.ArtikelID
AND p.GueltigAb <= XX
ORDER BY p.GueltigAb DESC
) AS Preis
FROM T_Artikel a
WHERE a.ArtikelID = 123456789
Artikel die noch keinen Preis haben, werden mit NULL in der Spalte [Preis] angezeigt.
Gruß Kai
-
Moin,
du könntest das mit "PATINDEX" http://msdn.microsoft.com/en-us/library/ms188395.aspx machen. Der Befehl sucht z.B. in einer Spalte eine Zeichenfolge und gibt Dir die erste gefundene Position aus. Dann könntest Du temporär das erste gefundene
"Berlin" ersetzen und nochmals den neuen String nach "Berlin" durchsuchen. Findet er nichts mehr weißt du, das "Berlin" nur einmal vorhanden ist (und wirst wohl nichts ersetzen).
Findet er noch ein weiteres "Berlin", kann nach Deiner Definition das erste dann ersetzt werden.
Um das ganze dann in einem SQL-Befehl unterzubringen, kommt zur Entscheidungsfindung noch "CASE WHEN" ins Spiel ...
Gruß Kai
-
:suspect:
:rolleyes:aha... soweit war ich auch schon....
NATÜRLICH... :schreck:... du hast vollkommen recht....
Keep it simple!
Habe seit gestern auch ne Lösung gefunden.
Problem war, dass die Entwickler zwichen dem From und dem With kein Space sondern TAB verwendet haben.
Manchmal auch zwischen With und (TABLOCKX).
Mein Filter den ich definiert hatte lieferte keine Ergebnisse.
WHERE sysc.definition LIKE '% with %(TABLOCKX) %'
VG Frank
Du hast noch zusätzliche Leerzeichen im SuchString. Das passt dann nicht auf z.B. "WITH{CRLF}TABLOCKX"
WHERE sysc.definition LIKE '%WITH%TABLOCKX%'
Der sollte genau das gewünschte finden.
Gruß Kai
-
Moin,
evtl. einfach nur mit
...
WHERE sysc.definition LIKE '%WITH%TABLOCKX%'
oder
...
WHERE sysc.definition LIKE '%WITH TABLOCKX%'
Gruß Kai
-
Moin,
ist etwas abstrakt was du da möchtest. Denke mal über eine
Normalisierung der Daten nach, wenn das möglich ist.
Ähnliche Beispiele die evtl. weiterhelfen, die korrekten Befehle hast du ja schon genannt:
http://www.mcseboard.de/ms-sql-server-forum-81/string-teile-feldes-selektieren-185551.html
http://www.mcseboard.de/ms-sql-server-forum-81/suchen-loeschen-bestimmter-zeichenanzahl-182008.html
Gruß Kai
-
Moin,
ich hab nicht genau verstanden, ob die Werte in der gleichen oder in einer anderen Tabelle stehen.
Meiner Meinung nach kann man in beiden Fällen das nur per Trigger (After oder Instead of, siehe OH) lösen.
Gruß Kai
-
Moin,
Das sollte auch nur ein Denkanstoß sein ;)ja das hab ich mir schon gedacht :-)
Ich fand dann die Fragestellung spannend und wollte die dann auch komplett lösen.
Also im Ansatz glaub ich habe ich verstanden worauf du hinaus willst, allerdings kriege ich das so nicht hin...Guck Dir mal das Ergebnis der Abfrage mit dem Group By separat an.
Das gibt Dir eine Tabelle zurück, die das Datum und den Maxwert in einer Zeile liefert.
- INNER JOIN (siehe Onlinehilfe) verknüpft 2 oder mehr Tabellen miteinander
- Die Schreibweise (SELECT ... ) b "übergibt" das Ergebnis an "INNER JOIN", der das Ergebnis wie eine Tabelle behandelt.
Komplette Tabelle ("a") enthält z.B.
Datum Uhr Wert
12.05.2012 11:15 47
12.05.2012 12:25 11
12.05.2012 11:58 55
Unser View ("b") enthält dann:
Datum Wert
12.05.2012 55
nun JOINe beide miteinander mittels Datum und Uhrzeit (siehe ON im INNER JOIN-Statement), stell Dir beide Ergebnisse nebeneinander vor:
a b
a.Datum a.Uhr a.Wert b.Datum b.Wert
12.05.2012 11:15 47
12.05.2012 11:25 11
12.05.2012 11:58 55 12.05.2012 55 <- Treffer des INNER JOIN
da hast du nun die eine Zeile
12.05.2012 11:58 55
als Ergebnis vorliegen (Doppelte Zeilen können bei gleichen MaxWerten pro Datum auftreten).
Gruß Kai
After Insert Trigger
in MS SQL Server Forum
Geschrieben
Moin,
wenn du eine Variable in einem SELECT zuweist (> SELECT @Variable = Zelle FROM inserted) war die Frage was passiert, wenn im Statement mehrere Zeilen als Ergebnis vorkommen.
Die Variable speichert ja nur einen Wert, die Anzahl der Datensätze in inserted ist aber größer 1.
Genauso kann es passieren, dass dein Insert-Statement kein Datensatz einfügt, weil die Bedingung nicht erfüllt ist. Der Trigger wird dann aber trotzdem ausgelöst:
Trigger wird gestartet, dein o.g. "SELECT @Variable = Zelle FROM inserted" ergibt dann @Variable = NULL Bei SQL immer mengenbasiert denken, nicht zeilenweile (ok, da gibt es auch Möglichkeiten), daher der Einwand was passiert beim Einfügen von keinem , einem oder mehreren Datensätzen.
Gruß Kai