Scripts SQL Server ré-exécutables

Quelles sont les meilleures pratiques pour vous assurer que votre SQL peut être exécuté à plusieurs resockets sans recevoir d'erreurs lors des exécutions suivantes?

par exemple

edit: Je cherchais quelque chose comme ça:

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 énoncés comme celui-ci ou quelque chose de mieux?

edit: J'aime la suggestion de Jhonny:

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

Je fais cela pour append des colonnes:

 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] 

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

MODIFIER

En réponse à votre édition 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 

Pour append à votre list:

  • Si vous supprimez des tables qui existent avant de les créer à nouveau, supprimez d'abord leurs dependencies, 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

Mais finalement, je voudrais aller avec l'un des suivants:

  • Maintenir un schéma de versioning 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 datatables existantes vers les instructions INSERT et recréez entièrement la database entière.

J'ai récemment trouvé un check-in pour l'existence que je ne connaissais pas et je l'ai aimé car il est plus court

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

avant, j'avais l'habitude d'utiliser

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

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

Pour rendre les choses plus faciles, je configure le studio de gestion en objects de script en tant que rerunnable

  1. devises
  2. Options
  3. Explorateur d'objects SQL Server
  4. Script
  5. Options de script d'object
  6. Inclure SI Pas existant Clause Vrai

Pour gérer les schémas, examinez un outil de migration. Je pense que LiquiBase fonctionnerait pour SQL Server.

Vous devrez également vérifier les foreign keys sur toutes les tables que vous pourriez supprimer / recréer. En outre, tenez count des modifications de données que vous pourriez apporter – supprimez des lignes avant d'essayer d'insert une seconde fois, etc.

Vous pouvez également append du code pour vérifier datatables avant de supprimer les tables afin de ne pas supprimer les tables déjà utilisées.

Pour une instruction de traitement par lots SQL, vous pouvez émettre

Ceci est juste un FYI, je l'ai juste 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 l'ai juste couru 10 fois

Début de la boucle d'exécution Batch

exécution terminée 10 fois.

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

… et triggersurs, 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) au cas où vos noms standards permettent aux procédures et tables d'avoir noms similaires …

En outre, 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 déposer une table
  • prcTableColumnAdd, Proc pour append une colonne à une table
  • prcTableColumnRename, vous avez l'idée
  • prcTableIndexCreate

Un tel process rend la création de scripts de changement répétables (dans le même ou autre db) beaucoup plus facile.

/ B

J'ai décrit quelques vérifications dans mes conditions DDL 'IF not Exists' pour que les scripts SQL puissent être exécutés