Tengo una tabla de prueba simple como esta:
CREATE TABLE MyTable (x INT);
Dentro de una transacción, trato de agregar una columna y luego insertarla en la columna recién creada:
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;
El problema es un mensaje de error cuando ejecuto el código anterior:
Invalid column name 'SupplementalDividends'.
¿Por qué esto está causando un error? Si agrego la columna en un lote diferente, fuera de la transacción, funcionará. Mi problema es que quiero agregar la columna dentro de la transacción. ¿Por qué el error?
sql-server
sql-server-2008-r2
t-sql
Tom Baxter
fuente
fuente
schema.ObjectName
. Un buen comienzo para adaptar las buenas prácticas :-)Respuestas:
Solo quiero aclarar que este es un problema en tiempo de ejecución, no en tiempo de compilación, y que no tiene nada que ver con el hecho de que están en la misma transacción . Por ejemplo, supongamos que tenemos esta tabla:
El siguiente lote se analiza con éxito (tiempo de compilación), pero en el tiempo de ejecución obtiene el error que menciona en la pregunta:
En un editor de consultas en Management Studio, puede solucionarlo fácilmente, ya sea:
Poner un separador de lotes entre ellos, así:
Si está ejecutando esto desde fuera de SQL Server (por ejemplo, enviando un lote SQL desde el código de su aplicación), simplemente puede enviar los dos lotes por separado de una manera similar, o si absolutamente necesita enviarlo como un único lote, puede use SQL dinámico (como en la respuesta de Gianluca ) para diferir la resolución de nombres.
fuente
Es un problema vinculante. El código está enlazado a los metadatos de la tabla en tiempo de compilación y no está enlazado tarde. Intente usar EXEC y SQL dinámico para superar esta limitación:
Otra opción es utilizar un procedimiento almacenado para insertar los datos: el enlace tardío se aplica al procedimiento almacenado, pero no a las consultas ad-hoc. Nuevamente, tendría que usar SQL dinámico para crear el procedimiento, pero podría facilitarle el paso de parámetros:
Un procedimiento almacenado temporal también funcionaría:
fuente
Tengo curiosidad por saber por qué está alterando una tabla e insertando un valor en esa columna dentro de la misma transacción.
Casi no hay posibilidad de que alguna vez deba modificar la tabla (de la misma manera), a menos que se revierta cada hora / día, entonces, ¿por qué hacerlo dentro de una transacción?
Su modificación aún no se ha confirmado y, por lo tanto, no se encuentra cuando intenta insertarla.
Mi consejo es separar sus tareas DDL y DML (al menos en transacciones separadas de todos modos).
fuente