Estoy generando un script para migrar automáticamente los cambios de varias bases de datos de desarrollo a la etapa de preparación / producción. Básicamente, se necesitan varios scripts de cambio y los fusiona en un solo script, envolviendo cada script en una IF whatever BEGIN ... ENDdeclaración.
Sin embargo, algunos de los scripts requieren una GOdeclaración para que, por ejemplo, el analizador de SQL conozca una nueva columna después de que se cree.
ALTER TABLE dbo.EMPLOYEE
ADD COLUMN EMP_IS_ADMIN BIT NOT NULL
GO -- Necessary, or next line will generate "Unknown column: EMP_IS_ADMIN"
UPDATE dbo.EMPLOYEE SET EMP_IS_ADMIN = whatever
Sin embargo, una vez que envuelvo eso en un IFbloque:
IF whatever
BEGIN
ALTER TABLE dbo.EMPLOYEE ADD COLUMN EMP_IS_ADMIN BIT NOT NULL
GO
UPDATE dbo.EMPLOYEE SET EMP_IS_ADMIN = whatever
END
Falla porque estoy enviando un BEGINmensaje sin coincidencia END. Sin embargo, si elimino el GO, vuelve a quejarse de una columna desconocida.
¿Hay alguna forma de crear y actualizar la misma columna dentro de un solo IFbloque?
sql
sql-server
tsql
sql-server-2008
BlueRaja - Danny Pflughoeft
fuente
fuente

GOdebe estar en una línea por sí solo, por lo que puede buscar solo ese caso, y no todas las instancias de la palabraGO. 2) Siempre puede registrar qué declaraciones se completaron correctamente. O puede envolver todo en un try / catch y usar sus propios números de línea usando alguna variable, como @lineNo, de la que realiza un seguimiento e informa sobre el error. Dado que los está generando automáticamente, realizar cambios como este debería ser muy sencillo. Parece que simplemente no quieres explorar esta ruta cuando creo que hay soluciones para todas tus preocupaciones.Respuestas:
Tuve el mismo problema y finalmente logré resolverlo usando SET NOEXEC .
fuente
SQLCMDscript de modo SS (es decir, un script de implementación maestro) que llama (a través de un:rcomando) a otros scripts SS (es decir, scripts de subdespliegue) con algunas de esas llamadas dentro deifdeclaraciones. Las Respuestas de Oded, Mellamokb y Andy Joiner de incluir todas esas Declaraciones enexecLlamadas /begin-endno son para empezar. Además, el métodobegin-endno funcionará si hay unacreateinstrucción (por ejemplo, requiere ungoprevio explícito ). Pero, hombre, "¡Santos dobles negativos, Batman!" ;)if), prefijaría el bloque con un-- If whatevercomentario, sangraría el bloque y fijaría el bloque con un--end If whatevercomentario.GOno es SQL, es simplemente un separador de lotes utilizado en algunas herramientas de MS SQL.Si no lo usa, debe asegurarse de que las declaraciones se ejecuten por separado, ya sea en diferentes lotes o mediante el uso de SQL dinámico para la población (gracias @gbn):
fuente
IFbloque.;aquí? - Acaba de editar su respuesta: o);tampoco funciona: el analizador todavía me da "Nombre de columna no válido 'EMP_IS_ADMIN'".Puede intentar
sp_executesqldividir el contenido entre cadaGOdeclaración en una cadena separada para que se ejecute, como se muestra en el siguiente ejemplo. Además, hay una variable @statementNo para rastrear qué declaración se está ejecutando para una fácil depuración donde ocurrió una excepción. Los números de línea estarán relacionados con el comienzo del número de declaración relevante que causó el error.También puede ejecutar fácilmente declaraciones de varias líneas, como se demuestra en el ejemplo anterior, simplemente envolviéndolas entre comillas simples (
'). No olvide escapar las comillas simples contenidas dentro de la cadena con una comilla simple doble ('') al generar los scripts.fuente
SELECT * <newline> FROM whatever. Si ejecuto cada línea con su propia declaración EXEC, eso se romperá. ¿O estás sugiriendo que rompa con cadaGOdeclaración?Finalmente logré que funcionara reemplazando cada instancia de
GOen su propia línea conEsto es muy preferible a envolver cada grupo de declaraciones en una cadena, pero aún está lejos de ser ideal. Si alguien encuentra una solución mejor, publíquela y la aceptaré.
fuente
IFbloque). Parece que simplemente no hay una buena manera de hacer esto en SQL.set noexecrespuesta de Mina Jacob es la ÚNICA respuesta práctica hasta ahora para usar en unSQLCMDscript en modo SS (es decir, un script de implementación maestro) que llama (a través de un:rcomando) a otros scripts SS (es decir, scripts de subdespliegue) con algunas de esas llamadas dentro deifdeclaraciones. Las Respuestas de Oded, Mellamokb y Andy Joiner de incluir todas esas Declaraciones enexecLlamadas /begin-endno son para empezar. Además, el métodobegin-endno funcionará si hay unacreateinstrucción (por ejemplo, requiere ungoprevio explícito ).Puede incluir las declaraciones en BEGIN y END en lugar del GO entre
(Probado en la base de datos Northwind)
Editar: (Probablemente probado en SQL2012)
fuente
set noexecrespuesta de Mina Jacob es la ÚNICA respuesta práctica hasta ahora para usar en unSQLCMDscript de modo SS (es decir, un script de implementación maestro) que llama (a través de un:rcomando) a otros scripts SS (es decir, scripts de subdespliegue) con algunas de esas llamadas dentro deifdeclaraciones. Las Respuestas de Oded, Mellamokb y Andy Joiner de incluir todas esas Declaraciones enexecLlamadas /begin-endno son para empezar. Además, el métodobegin-endno funcionará si hay unacreateinstrucción (por ejemplo, requiere ungoprevio explícito ).Puede probar esta solución:
fuente
He usado
RAISERRORen el pasado para estofuente
Puede incorporar declaraciones
GOTOyLABELpara omitir el código, dejando lasGOpalabras clave intactas.fuente