2012-09-21 31 views
19

¿Alguien ve qué le pasa a este código para SQL Server?Nombre de columna inválido en la actualización del servidor sql después de crear la columna

IF NOT EXISTS(SELECT * 
       FROM sys.columns 
       WHERE Name = 'OPT_LOCK' 
        AND object_ID = Object_id('REP_DSGN_SEC_GRP_LNK')) 
    BEGIN 
     ALTER TABLE REP_DSGN_SEC_GRP_LNK 
     ADD OPT_LOCK NUMERIC(10, 0) 

     UPDATE REP_DSGN_SEC_GRP_LNK 
     SET OPT_LOCK = 0 

     ALTER TABLE REP_DSGN_SEC_GRP_LNK 
     ALTER COLUMN OPT_LOCK NUMERIC(10, 0) NOT NULL 
    END; 

Cuando ejecuto esto, me sale:

Msg 207, nivel 16, estado 1, línea 3
nombre de columna no válido 'OPT_LOCK'.

en el comando de actualización.

Gracias.

Respuesta

33

En este caso puede evitar el problema agregando la columna como NOT NULL y estableciendo los valores para las filas existentes en una declaración as per my answer here.

En general, el problema es un problema de análisis/compilación. SQL Server intenta compilar todas las instrucciones en el lote antes de ejecutar cualquiera de las instrucciones.

Cuando una instrucción hace referencia a una tabla que no existe en absoluto, la sentencia está sujeta a compilación diferida. Cuando la tabla ya existe arroja un error si hace referencia a una columna no existente. La mejor manera de evitar esto es hacer el DDL en un lote diferente del DML.

Si una instrucción hace referencia tanto a una columna no existente en una tabla existente como a una tabla inexistente, el error puede o no producirse antes de que la compilación se difiera.

Puede o bien enviarlo por lotes (por ejemplo, usando el separador de lotes GO en las herramientas de cliente) o llevar a cabo en un ámbito secundario que se compila por separado utilizando EXEC o EXEC sp_executesql.

El primer enfoque requeriría que refactorice su código ya que IF ... no puede abarcar lotes.

IF NOT EXISTS(SELECT * 
       FROM sys.columns 
       WHERE Name = 'OPT_LOCK' 
        AND object_ID = Object_id('REP_DSGN_SEC_GRP_LNK')) 
    BEGIN 
     ALTER TABLE REP_DSGN_SEC_GRP_LNK 
     ADD OPT_LOCK NUMERIC(10, 0) 

     EXEC('UPDATE REP_DSGN_SEC_GRP_LNK SET OPT_LOCK = 0'); 

     ALTER TABLE REP_DSGN_SEC_GRP_LNK 
     ALTER COLUMN OPT_LOCK NUMERIC(10, 0) NOT NULL 
    END; 
+1

El EXEC se acercó funcionó para mí. ¡Gracias! – feradz

+0

Este es el enfoque que he estado utilizando durante años, y siempre me sorprende que nos veamos obligados a tomar esta ruta incómoda de sql dinámica cada vez que queremos agregar una nueva columna y llenarla con datos ... –

0

Para su información, se puede reemplazar el IF NOT EXISTS con la función COL_LENGTH. Se necesitan dos parámetros,

  1. nombre de la tabla y

  2. columna que está buscando

Si se encuentra la Columna entonces se devuelve el rango del tipo de datos de la columna Ej: Int (4 bytes), cuando no se encuentra, devuelve un NULL.

Por lo tanto, puede usar esto de la siguiente manera y también combinar 3 declaraciones en una.

IF (SELECT COL_LENGTH('REP_DSGN_SEC_GRP_LNK','OPT_LOCK')) IS NULL 

BEGIN 

    ALTER TABLE REP_DSGN_SEC_GRP_LNK 
    ADD OPT_LOCK NUMERIC(10, 0) NOT NULL DEFAULT 0 

END; 

Lo hace más simple.

Cuestiones relacionadas