Ich habe eine einfache Testtabelle wie diese:
CREATE TABLE MyTable (x INT);
Innerhalb einer Transaktion versuche ich, eine Spalte hinzuzufügen und dann in die neu erstellte Spalte einzufügen:
BEGIN TRANSACTION;
PRINT 'Adding column, ''SupplementalDividends'', to MyTable table.';
ALTER TABLE MyTable
ADD SupplementalDividends DECIMAL(18,6);
PRINT 'Column added successfully....';
PRINT 'Ready to INSERT into MyTable ...';
INSERT INTO MyTable (x, SupplementalDividends)
VALUES (1, 3.2);
PRINT '**** CHANGES COMPLETE -- COMMITTING.';
COMMIT TRANSACTION;
Das Problem ist eine Fehlermeldung, wenn ich den obigen Code ausführe:
Invalid column name 'SupplementalDividends'.
Warum verursacht dies einen Fehler? Wenn ich die Spalte außerhalb der Transaktion in einem anderen Stapel hinzufüge, funktioniert dies. Mein Problem ist, dass ich die Spalte innerhalb der Transaktion hinzufügen möchte . Warum der Fehler?
sql-server
sql-server-2008-r2
t-sql
Tom Baxter
quelle
quelle
schema.ObjectName
. Ein guter Anfang, um gute Praktiken anzupassen :-)Antworten:
Ich möchte nur klarstellen, dass dies zur Laufzeit ein Problem ist, nicht zur Kompilierungszeit, und nichts damit zu tun hat, dass sie sich in derselben Transaktion befinden . Nehmen wir zum Beispiel an, wir haben diese Tabelle:
Der folgende Stapel wird erfolgreich analysiert (Kompilierungszeit), aber zur Laufzeit wird der Fehler angezeigt, den Sie in der Frage erwähnt haben:
In einem Abfrageeditor in Management Studio können Sie dies einfach umgehen, indem Sie:
Setzen Sie einen Batch- Separator zwischen sie, wie folgt:
Wenn Sie dies von außerhalb von SQL Server ausführen (z. B. Senden eines SQL-Stapels aus Ihrem Anwendungscode), können Sie die beiden Stapel einfach auf ähnliche Weise separat senden, oder wenn Sie ihn unbedingt als einzelnen Stapel senden müssen, können Sie dies Verwenden Sie dynamisches SQL (wie in Gianlucas Antwort ), um die Namensauflösung zu verschieben.
quelle
Es ist ein verbindliches Problem. Der Code wird zur Kompilierungszeit an die Metadaten der Tabelle gebunden und ist nicht zu spät gebunden. Versuchen Sie, EXEC und dynamisches SQL zu verwenden, um diese Einschränkung zu überwinden:
Eine andere Option ist die Verwendung einer gespeicherten Prozedur zum Einfügen der Daten: Die späte Bindung gilt für gespeicherte Prozeduren, jedoch nicht für Ad-hoc-Abfragen. Auch hier müssten Sie dynamisches SQL verwenden, um die Prozedur zu erstellen, aber es könnte Ihnen das Übergeben von Parametern erleichtern:
Eine temporär gespeicherte Prozedur würde ebenfalls funktionieren:
quelle
Ich bin gespannt, warum Sie innerhalb derselben Transaktion eine Tabelle ändern und einen Wert in diese Spalte einfügen.
Es besteht fast keine Chance, dass Sie die Tabelle jemals wieder ändern müssen (genau so), es sei denn, sie wird jede Stunde / jeden Tag zurückgesetzt. Warum also innerhalb einer Transaktion?
Ihre Änderung wurde noch nicht festgeschrieben und wird daher nicht gefunden, wenn Sie versuchen, sie einzufügen.
Mein Rat ist, Ihre DDL- und DML-Aufgaben zu trennen (zumindest in getrennten Transaktionen).
quelle