Dans le cadre de notre processus de construction, nous exécutons un script de mise à jour de la base de données lorsque nous déployons du code dans 4 environnements différents. De plus, puisque la même requête sera ajoutée jusqu'à ce que nous mettions une version en production, elle a pour pouvoir s'exécuter plusieurs fois sur une base de données donnée. Comme ça:
IF NOT EXISTS (SELECT * FROM sys.tables WHERE object_id = OBJECT_ID(N'[Table]'))
BEGIN
CREATE TABLE [Table]
(...)
END
Actuellement, j'ai une instruction create schema dans le script de déploiement/build. Où dois-je rechercher l'existence d'un schéma?
Recherchez-vous sys.schemas ?
IF NOT EXISTS (SELECT * FROM sys.schemas WHERE name = 'jim')
BEGIN
EXEC('CREATE SCHEMA jim')
END
Notez que le CREATE SCHEMA
doit être exécuté dans son propre lot (par la réponse ci-dessous )
@bdukes a raison sur l'argent pour déterminer si le schéma existe, mais l'instruction ci-dessus ne fonctionnera pas dans SQL Server 2005. CREATE SCHEMA <name>
doit s'exécuter dans son propre lot. Une solution consiste à exécuter le CREATE SCHEMA
instruction dans un exec.
Voici ce que j'ai utilisé dans mes scripts de construction:
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
Juste pour être extra "défensif", la version suivante génère une erreur de conversion de type pour tenir compte de la possibilité (quoique peu probable) de> 1 correspondant à Schema
's similaire à la façon dont le code de validation souvent intentionnellement Throw Les exceptions sont parce que je pense qu'il est bon de le faire et je pense que c'est la "meilleure pratique" pour tenir compte de tous les résultats de retour possibles, même si cela est peu probable et même si c'est juste pour générer une exception fatale car les effets connus de l'arrêt du traitement sont généralement meilleurs que les effets en cascade inconnus d'erreurs non piégées. Parce que c'est hautement improbable, je ne pensais pas que cela valait la peine d'un contrôle séparé de Count
+ Throw
ou Try
-Catch
-Throw
pour générer une erreur fatale plus conviviale mais néanmoins une erreur fatale.
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
Ensuite:
if @HasSchemaX = 1
begin
...
end -- if @HasSchemaX = 1
C'est vieux donc je me sens obligé d'ajouter: Pour SQL SERVER 2008+ Tout cela fonctionne (pour la partie select), puis utilisez EXECUTE('CREATE SCHEMA <name>')
pour le créer réellement sur des résultats négatifs.
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