La problématique :
Beaucoup d'applications ont un nombre important de procédure stockées. Plutôt que d'avoir "a", puis "a_old", "a_old2" etc etc (qui ne servent à rien dans 99% des cas en plus), on voudrait stocker nos définition de table/vues/ procédures stockées/fonctions/whatever (on se limitera à ces 4 là pour le moment ) sur un serveur Subversion (en parallèle du projet associé), afin d'assurer un historique de version.
Il est bien entendu hors de question de stocker tout ça sur le serveur de base de données (tel que c'est fait actuellement), de plus on ne gère pas d'historique de structure des tables.
On a donc une pléthore de procédure stockées qui ne sont plus valables (car elles ont étés renommées pour sauvegarde, et les structures ont changé entre temps) ou plus d'actualité (car remplacées par d'autres)
Le but est d'extraire toutes ces définitions de la base de données, stocker le tout dans des fichiers, et balancer sur le serveur SVN.
Et voilà l'idée que j'ai :
Grâce à C# et à la bibliothèque SharpSvn, je veux extraire les définitions des objets et contrôler le SVN depuis un programme (histoire d'en avoir le moins à faire plus tard, c'est feignant un développeur/DBA (et encore pire un développeur DBA comme moi (oui je fais les 2 tout le temps)))
L'extraction des définitions d'objets ne pose pas de problème
SELECT OBJECT_DEFINITION(OBJECT_ID(@objectName))
me renvoie la définition d'un objet au dernier CREATE ou ALTER
Seulement si on la renomme (via sp_rename) sans l'altérer par la suite, la définition de l'objet ne change pas (ca serait trop beau) ou si on essaie de remonter une procédure existante (lors d'un update du SVN par exemple), il faut penser à altérer (ou supprimer) l'existant, mais seulement dans le cas où la procédure existe.
Donc, je souhaite remplacer
CREATE type schema.nom [@arguments facultatifs] AS
par
__SVN__ACTION__ type schema_reel.nom_reel [@arguments facultatifs] AS
avec toutes les contraintes que m'imposent Sql Server bien évidemment, c'est à dire
- Garder les éventuels commentaires qui se seraient glissés dans la définition entre le CREATE et le premier AS significatif
- gérer les nom entre crochets (si jamais on a une procédure qui s'appelle [AS] ou avec un espace, un point ou des accents... ce n'est pas le cas chez nous, mais peut être que d'autres auront ce problème)
- éventuellement supprimer les espaces non significatifs lors de l'export de la définition (Entre le premier CREATE significatif et le premier AS significatif bien entendu, dans le reste on touche pas)
Ce que j'appelle significatif, c'est qu'il a un sens pour Sql Server
1 2 3 4 5 6
| -- AS non significatif
/* AS non significatif */
'AS non significatif...
RHAAA j''avais pas pensé à celui là dans une valeur par défaut'
CREATE PROCEDURE [AS] AS /* significatif */
SELECT 1 AS /* significatif */ X |
Et il est hors de question d'utiliser des triggers (c'est une philosophie dans la boite)
Voici mon cauchemard
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| -- Ce CREATE va créer la procédure stockée
/* qui risque me poser le plus de problème
et de retournement de cerveau */
CREATE PROCEDURE /* ou peut être une fonction serait mieux */
dbo
. [un as de @pique] -- coucou
@as VARCHAR = 'Ceci est un AS de pique'
AS
BEGIN
SELECT @as AS RETOUR
END
GO
EXEC sp_rename 'un as de @pique', 'un as de @coeur'
GO |
J'ai le nom réel stocké à part. Lors de la lecture de la définition de cette procédure :
SELECT OBJECT_DEFINITION(OBJECT_ID('un as de @coeur'))
je vais recevoir
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| -- Ce CREATE va créer la procédure stockée
/* qui risque me poser le plus de problème
et de retournement de cerveau */
CREATE PROCEDURE /* ou peut être fonction */
dbo
. [un as de @pique] -- coucou
@as VARCHAR = 'Ceci est un AS de pique'
AS
BEGIN
SELECT @as AS RETOUR
END |
Lors de la réinsertion dans la BDD, c'est au programme de se rendre compte que non, la procédure ne s'appelle plus "un as de @pique" mais "un as de @coeur", et que, comme elle existe déjà, je dois faire un "ALTER PROCEDURE", et non pas un "CREATE PROCEDURE"
Partager