Inkrementierten Sequenznummer, die auf SQL einfügen
Gibt es eine einfache Möglichkeit, um mehrere Zeilen einfügen und die Schrittweite ein bestimmtes Feld, SQL Server 2005 verwenden?
Hinweis, ich bin nicht auf der Suche nach einer Lösung, die eine identity
Spalte - siehe unten die Frage nach einer Erklärung für die
(Das folgende schema und die Daten repliziert worden sind,hier in diesem SQLFiddle.)
Betrachten Sie beispielsweise die folgende Tabelle und die Daten...
CREATE TABLE #TEMPTABLE (
[PKID] INT IDENTITY, [FKID] INT, [MYTEXT] VARCHAR(10), [SEQUENCE] INT
)
INSERT INTO #TEMPTABLE ([FKID], [MYTEXT], [SEQUENCE]) VALUES (1, 'one', 1)
INSERT INTO #TEMPTABLE ([FKID], [MYTEXT], [SEQUENCE]) VALUES (1, 'two', 2)
-- Table data
PKID FKID MYTEXT SEQUENCE
1 1 one 1
2 1 two 2
Und die folgenden Daten an, die eingefügt werden...
DECLARE @FKID INT
SET @FKID = 1
DECLARE @NEWDATA XML
SET @NEWDATA = '<data><text>three</text><text>four</text></data>'
Können die folgenden geschrieben werden, so dass die SEQUENCE
Feld kommt als 1,2,3,4
statt der 1,2,3,3
aktuell?
INSERT INTO #TEMPTABLE ([FKID], [MYTEXT], [SEQUENCE])
SELECT @FKID,
X.value('.','VARCHAR(10)'),
(SELECT ISNULL(MAX([SEQUENCE]),0)+1 FROM #TEMPTABLE WHERE [FKID]=@FKID)
FROM @NEWDATA.nodes('/data/text') AS X(X)
-- Actual result...
PKID FKID MYTEXT SEQUENCE
1 1 one 1
2 1 two 2
3 1 three 3
4 1 four 3 <-- Issue
-- Required result...
PKID FKID MYTEXT SEQUENCE
1 1 one 1
2 1 two 2
3 1 three 3
4 1 four 4
Update:
Antwort auf den Kommentar von @marc_s...
Identität wäre die beste Lösung für 2005... beste Lösung durch weit - warum tun Sie explizit ausschließen und bestehen auf Ihre eigenen Rollen? (mit all den Risiken verursachen Duplikate, und so weiter....)
Der Tabelle zu Frage halten wird, mehrere sets von SEQUENCE
Werte, jedes "set" auf der Grundlage der FKID
Wert... also der Tabelle halten konnte Daten entlang dieser Linien...
PKID FKID MYTEXT SEQUENCE
1 1 one 1
2 1 two 2
3 1 three 3
4 1 four 4
5 2 ett 1
6 2 tva 2
7 2 tre 3
Ja, @Pieter, ich bin mir sicher, es wäre einfacher - leider bin ich stecken mit 2005, als das ist das minimum unterstützt, DB und viele unserer Kunden sind immer noch mit es
Weil, @marc_s, die Sequenz wird direkt mit der foreign key-Spalte. I. e.
FKID=1
können mehrere Zeilen mit SEQUENCE=1,2,3
und FKID=2
können auch SEQUENCE=1,2
. Sorry, wenn ich das nicht machen, klar in der OPirgendeinem Grund Sie nicht verwenden können, eine variable, es zu tun? Erklären, und die Schrittweite, um Sie von Ihrer select-Anweisung? Schreiben Sie die variable am Ende.
Sorry @Random, verstehe ich nicht so würden Sie eine variable verwenden... bitte fühlen Sie sich frei, um eine Antwort mit Lösung
InformationsquelleAutor freefaller | 2013-03-20
Du musst angemeldet sein, um einen Kommentar abzugeben.
Kann ich nicht testen auf 2005, aber Sie sollten in der Lage sein zu verwenden, CTE-einfach gut zu der Anzahl der Dinge;
die das Ergebnis liefert:
UPDATE
Wenn die Abfrage immer legen Sie jeweils nur eine FKID, die folgende vereinfachte version würde auch funktionieren (die erforderlichen änderungen an Ihrer aktuellen Abfrage sind hervorgehoben):
Zweck der
(SELECT 1)
imROW_NUMBER
'sORDER BY
- Klausel zu vermeiden, die Angabe einer bestimmten Reihenfolge. Es kann geändert werden, um etwas anderes (z.B.X.value('.','VARCHAR(10)'
), wenn nötig.+1
von der Unterabfrage hinzufügen+ROW_NUMBER() ...
nach der Unterabfrage wäre genug, d.h. der Ausdruck für dieSEQUENCE
Spalte würde dann so Aussehen:(SELECT ISNULL(MAX([SEQUENCE]),0) FROM TEMPTABLE WHERE [FKID]=cte.fkid) + ROW_NUMBER() OVER (ORDER BY (SELECT 1))
.Danke, Joachim, für deine Antwort, Sie waren auf jeden Fall in die richtige Richtung. Aber @AndriyM, Sie treffen den Nagel auf den Kopf, und das ist genau das was ich brauchte (obwohl die
[FKID]=ctr.fkid
sollte[FKID]=@FKID
). Wenn Sie, dass eine Antwort, die ich gerne daneben.Hätte ich geschrieben meine Antwort, wenn es wirklich anders war, von diesem, die funktioniert gut für mich by the way. Das einzige Problem mit dieser Antwort, die ich sehen kann, ist, dass, während die Prüfung, Joachim Hinzugefügt eine weitere Sache, die
five
, um die@NEWDATA
XML, aber vergessen zu reflektieren, dass in der gebuchten Ausgabe. Ich würde auch behaupten, dass in diesem besonderen Lösung, welche einen CTE, beide[FKID]=cte.fkid
und[FKID]=@FKID
perfekt funktionieren. In der Zeit jedoch, möchten Sie vielleicht ändern Sie die CTE zu erzeugen Zeilen für mehrere FKIDs, und[FKID]=cte.fkid
besser funktionieren würde.Ja, ich verstehe, was du sagst @AndriyM - aber die Abfrage wird immer nur um eine einzelne FKID zu einer Zeit, so einfach mit der
ROW_NUMBER() OVER (ORDER BY (SELECT 1))
macht genau das, was ich brauche, ohne den Einsatz des CTE. Wenn Sie glücklich sind, für Joachim um die mark, dann bin ich fein mit. Danke Euch beiden für Eure HilfeInformationsquelleAutor Joachim Isaksson
Wie etwa
3
erscheinen zweimal. Auch dies würde nicht berücksichtigen, den (unwahrscheinlichen, aber dennoch möglichen) situation, wo dieSEQUENCE
ist nicht zusammenhängend von1
Du hast auch einen kleinen Tippfehler... sollte
Count(*),0
stattCount(*)),0
. Fühlt sich nicht richtig Bearbeiten jemand anderes beantworten, wenn ich die OP! 🙂InformationsquelleAutor Charles Bretana
Versuchen Sie dies:
nachgeben:
(1) Die
with
block einfach versorgt einige test-Daten zur überprüfung. (2) Die übrigenselect
- Anweisung ersetzen soll dieselect
Klausel in Ihreminsert
- Anweisung.InformationsquelleAutor Pieter Geerkens