2009-04-03 8 views
12

Quelles sont les meilleures pratiques pour garantir que votre SQL peut être exécuté de manière répétée sans recevoir d'erreurs lors des exécutions suivantes?Scripts SQL Server réactivables

par exemple.

  • vérifier que les tables ne sont pas déjà avant de les créer
  • vérifier que les colonnes ne sont pas déjà avant de créer ou renommer
  • transactions avec rollback en cas d'erreur
  • Si vous laissez tomber les tables qui existent avant en les créant à nouveau, abandonnez d'abord leurs dépendances, et n'oubliez pas de les recréer après
  • En utilisant CREATE OR ALTER PROCEDURE au lieu de CREATE PROCEDURE ou ALTER PROCEDURE si votre saveur de SQL le supporte
  • Maintenir un schéma de gestion de version interne, de sorte que le même SQL ne soit pas exécuté deux fois en premier lieu. De cette façon, vous savez toujours où vous en êtes en regardant le numéro de version.
  • Exportez les données existantes vers les instructions INSERT et recréez complètement la base de données entière à partir de zéro.

  • suppression de tables avant de les créer (pas la chose la plus sûre jamais, mais fonctionnera dans un pincement si vous savez ce que vous faites)

modifier: Je cherchais quelque chose comme ceci:

IF EXISTS (SELECT * 
      FROM sys.objects 
      WHERE object_id = OBJECT_ID(N'[dbo].[foo]') 
        AND OBJECTPROPERTY(object_id, N'IsUserTable') = 1) 
DROP TABLE foo 

Est-ce que d'autres utilisent des instructions comme celle-ci ou quelque chose de mieux?

modifier: J'aime la suggestion de Jhonny:

IF OBJECT_ID('table_name') IS NOT NULL DROP TABLE table_name 

Je le fais pour les colonnes en ajoutant:

IF NOT EXISTS (SELECT * 
       FROM SYSCOLUMNS sc 
       WHERE EXISTS (SELECT id 
           FROM [dbo].[sysobjects] 
           WHERE NAME LIKE 'TableName' 
             AND sc.id = id) 
         AND sc.name = 'ColumnName') 
    ALTER TABLE [dbo].[TableName] ADD [ColumnName] 
+0

je supprimer la suppression de tables avant de les créer. Vous ne voudriez pas supprimer des tables contenant des données! –

+0

D'accord, ce n'est probablement pas la chose la plus sûre à faire. J'essayais juste de faire avancer le genre de réponses que je cherchais. –

Répondre

0

Pour maintenir les schémas, regardez un outil de migration. Je pense que LiquiBase fonctionnerait pour SQL Server.

4

Pour ajouter à votre liste:

  • Si vous laissez tomber les tables qui existent avant de les créer à nouveau, abandonner leurs dépendances première aussi, et ne pas oublier de les recréer après
  • En utilisant CREATE OR ALTER PROCEDURE au lieu de CREATE PROCEDURE ou ALTER PROCEDURE si votre goût de SQL supporte

Mais en fin de compte, j'irais avec une des options suivantes:

  • Maintenir un schéma de gestion de version interne, de sorte que le même code SQL ne soit pas exécuté deux fois en premier lieu. De cette façon, vous savez toujours où vous en êtes en regardant le numéro de version.
  • Exportez les données existantes vers les instructions INSERT et recréez complètement la base de données entière à partir de zéro.
+0

Bon conseil, avec le schéma de versioning interne – SQueek

0

Vous devrez également vérifier les clés étrangères sur les tables que vous pouvez supprimer/recréer. En outre, tenez compte des modifications de données que vous pouvez effectuer - supprimez des lignes avant d'essayer d'insérer une seconde fois, etc.

Vous pouvez également entrer du code pour vérifier les données avant de supprimer les tables afin de ne pas endommager les lignes. t supprimez les tables déjà utilisées.

5

Je pense que la pratique la plus importante pour assurer que vos scripts sont re-runnable est de ... les exécuter plusieurs fois contre une base de test après toute modification du script. Les erreurs que vous rencontrez devraient façonner vos pratiques.

EDIT

En réponse à votre modification sur la syntaxe, en général, je pense qu'il est préférable d'éviter les tables système en faveur des vues du système par exemple

if exists(Select 1 from information_schema.tables where table_name = 'sometable') 
    drop sometable 
go 
if exists(Select 1 from information_schema.routines where 
specific_name = 'someproc') 
    drop someproc 
0

Pour une instruction batch SQL, vous pouvez émettre

Ceci est juste un FYI, j'ai couru 10 fois

IF EXISTS (SELECT * 
      FROM sys.objects 
      WHERE object_id = OBJECT_ID(N'[dbo].[foo]') 
        AND OBJECTPROPERTY(object_id, N'IsUserTable') = 1) 
DROP TABLE foo 


GO 10 -- run the batch 10 times 

Ceci est juste un FYI, je viens couru 10 fois

Début boucle d'exécution de lot

exécution terminée 10 fois.

3

J'ai récemment trouvé un enregistrement pour l'existence que je ne connaissais pas et je l'ai aimé parce qu'il est plus court

IF OBJECT_ID('table_name') IS NOT NULL DROP TABLE table_name 

avant, je l'habitude d'utiliser

IF EXISTS (SELECT * FROM information_schema.tables WHERE table_name = 'table_name') 
DROP TABLE table_name 

qui J'ai trouvé utile parce que c'est un peu plus portable (MySql, Postgres, etc), en tenant compte des différences, bien sûr

3

Pour faciliter les choses ier configurer studio de gestion à l'écriture des objets comme rerunnable

  1. Outils
  2. options
  3. SQL Server l'Explorateur d'objets
  4. script
  5. options de script d'objet
  6. Inclure IF non d 'une clause vrai
0

La valeur "IF OBJECT_ID ('nom_table', 'U') IS NOT NULL" est bonne, elle peut également être utilisée pour les procédures: SI OBJECT_ID ('procname', 'P') N'EST PAS NULL ...

... et les déclencheurs, les vues, etc ... Probablement une bonne pratique pour spécifier le type (U pour table, P pour prog, etc.)ne pas se souvenir des lettres exactes pour tous les types) dans le cas où vos noms standard permettent aux procédures et tables d'avoir des noms similaires ...

De plus, une bonne idée pourrait être de créer vos propres procédures qui changent les tables, avec une gestion des erreurs propre à votre environnement. Par exemple:

  • prcTableDrop, Proc pour droping une table
  • prcTableColumnAdd, Proc pour ajouter une colonne à une table
  • prcTableColumnRename, vous obtenez l'idée
  • prcTableIndexCreate

tel procs rend la création de scripts de changement reproductibles (dans le même ou autre db) beaucoup plus facile.

/B

Questions connexes