J'ai une table de test simple comme celle-ci:
CREATE TABLE MyTable (x INT);
Dans une transaction, j'essaie d'ajouter une colonne, puis d'insérer dans la colonne nouvellement créée:
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;
Le problème est un message d'erreur lorsque j'exécute le code ci-dessus:
Invalid column name 'SupplementalDividends'.
Pourquoi cela provoque-t-il une erreur? Si j'ajoute la colonne dans un lot différent, en dehors de la transaction, cela fonctionnera. Mon problème est que je veux ajouter la colonne dans la transaction. Pourquoi l'erreur?
sql-server
sql-server-2008-r2
t-sql
Tom Baxter
la source
la source
schema.ObjectName
. Un bon début pour adapter les bonnes pratiques :-)Réponses:
Je veux juste préciser qu'il s'agit d'un problème au moment de l'exécution, pas de la compilation, et n'a rien à voir avec le fait qu'ils sont dans la même transaction . Par exemple, supposons que nous avons ce tableau:
Le lot suivant analyse correctement (au moment de la compilation), mais lors de l'exécution, il obtient l'erreur que vous mentionnez dans la question:
Dans un éditeur de requêtes dans Management Studio, vous pouvez contourner cela facilement, soit en:
Mettre un séparateur de lots entre eux, comme ceci:
Si vous l'exécutez depuis l'extérieur de SQL Server (par exemple, en envoyant un lot SQL à partir de votre code d'application), vous pouvez simplement envoyer les deux lots séparément de manière similaire, ou si vous devez absolument l'envoyer en tant que lot unique, vous pouvez utiliser le SQL dynamique (comme dans la réponse de Gianluca ) pour différer la résolution des noms.
la source
C'est un problème contraignant. Le code est lié aux métadonnées de la table au moment de la compilation et il n'est pas lié tardivement. Essayez d'utiliser EXEC et SQL dynamique pour surmonter cette limitation:
Une autre option consiste à utiliser une procédure stockée pour insérer les données: la liaison tardive s'applique à la procédure stockée, mais pas aux requêtes ad hoc. Encore une fois, vous devrez utiliser SQL dynamique pour créer la procédure, mais cela pourrait vous faciliter la transmission des paramètres:
Une procédure stockée temporaire fonctionnerait également:
la source
Je suis curieux de savoir pourquoi vous modifiez une table et insérez une valeur dans cette colonne dans la même transaction.
Il n'y a presque aucune chance que vous ayez besoin de modifier à nouveau la table (de la même manière exacte), à moins qu'elle ne soit annulée toutes les heures / jour, alors pourquoi le faire dans une transaction?
Votre modification n'a pas encore été validée et, par conséquent, il n'est pas trouvé lorsque vous essayez de l'insérer.
Mon conseil est de séparer vos tâches DDL et DML (au moins dans des transactions distinctes de toute façon).
la source