Pregunta

Como parte de nuestro proceso de compilación, ejecutamos un script de actualización de la base de datos a medida que implementamos código en 4 entornos diferentes. Además, dado que se agregará la misma consulta hasta que dejemos una versión en producción, tiene para poder ejecutarse varias veces en una base de datos determinada. Así:

IF NOT EXISTS (SELECT * FROM sys.tables WHERE object_id = OBJECT_ID(N'[Table]'))
BEGIN
  CREATE TABLE [Table]
  (...)
END

Actualmente tengo una declaración de creación de esquema en el script de implementación / compilación. ¿Dónde consulto la existencia de un esquema?

¿Fue útil?

Solución

¿Está buscando sys.schemas ?

IF NOT EXISTS (SELECT * FROM sys.schemas WHERE name = 'jim')
BEGIN
EXEC('CREATE SCHEMA jim')
END

Tenga en cuenta que el CREATE SCHEMA debe ejecutarse en su propio lote (según la respuesta a continuación )

Otros consejos

@bdukes tiene razón en el dinero para determinar si existe el esquema, pero la declaración anterior no funcionará en SQL Server 2005. CREATE SCHEMA <name> necesita ejecutarse en su propio lote. Una solución alternativa es ejecutar la instrucción CREATE SCHEMA en un ejecutivo.

Esto es lo que usé en mis scripts de compilación:

IF NOT EXISTS (SELECT 1 FROM sys.schemas WHERE name = '<name>')
BEGIN
    -- The schema must be run in its own batch!
    EXEC( 'CREATE SCHEMA <name>' );
END

Solo para ser extra " defensivo " ;, la siguiente versión genera un error de conversión de tipo para tener en cuenta la posibilidad (aunque poco probable) de > 1 coincidencia de Schema es similar a cómo el código de validación a menudo arroja intencionalmente excepciones porque creo que es bueno y creo que es & Quot; 'best practice' & Quot; para tener en cuenta todos los posibles resultados de retorno, aunque sea poco probable e incluso si es solo para generar una excepción fatal porque los efectos conocidos de detener el procesamiento generalmente son mejores que los efectos en cascada desconocidos de los errores no atrapados. Debido a que es altamente improbable, no pensé que valiera la pena hacer un Count check + Throw o Try - Catch - <=> para generar un error fatal más fácil de usar pero aún así un error fatal no obstante.

SS 2005-:

declare @HasSchemaX bit
set @HasSchemaX = case (select count(1) from sys.schemas where lower(name) = lower('SchemaX')) when 1 then 1 when 0 then 0 else 'ERROR' end

SS 2008+:

declare @HasSchemaX bit = case (select count(1) from sys.schemas where lower(name) = lower('SchemaX')) when 1 then 1 when 0 then 0 else 'ERROR' end

Entonces:

if @HasSchemaX = 1
begin
   ...
end -- if @HasSchemaX = 1

Esto es antiguo, así que me siento obligado a agregar: Para SQL SERVER 2008+ Todo esto funciona (para la parte seleccionada), luego use EXECUTE('CREATE SCHEMA <name>') para crearlo realmente con resultados negativos.

DECLARE @schemaName sysname = 'myfunschema';
-- shortest
If EXISTS (SELECT 1 WHERE SCHEMA_ID(@schemaName) IS NOT NULL)
PRINT 'YEA'
ELSE
PRINT 'NOPE'

SELECT DB_NAME() AS dbname WHERE SCHEMA_ID(@schemaName) IS NOT NULL -- nothing returned if not there

IF NOT EXISTS ( SELECT  top 1 *
                FROM    sys.schemas
                WHERE   name = @schemaName )
PRINT 'WOOPS MISSING'
ELSE
PRINT 'Has Schema'

SELECT SCHEMA_NAME(SCHEMA_ID(@schemaName)) AS SchemaName1 -- null if not there otherwise schema name returned

SELECT SCHEMA_ID(@schemaName) AS SchemaID1-- null if not there otherwise schema id returned


IF EXISTS (
    SELECT sd.SchemaExists 
    FROM (
        SELECT 
            CASE 
                WHEN SCHEMA_ID(@schemaName) IS NULL THEN 0
                WHEN SCHEMA_ID(@schemaName) IS NOT NULL THEN 1
                ELSE 0 
            END AS SchemaExists
    ) AS sd
    WHERE sd.SchemaExists = 1
)
BEGIN
    SELECT 'Got it';
END
ELSE
BEGIN
    SELECT 'Schema Missing';
END
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top