IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Développement SQL Server Discussion :

Confusions sur les permissions d'existence des tables


Sujet :

Développement SQL Server

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    430
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Octobre 2006
    Messages : 430
    Points : 103
    Points
    103
    Par défaut Confusions sur les permissions d'existence des tables
    Bonjour

    J'avais créer ma procédure stockée sur le serveur de développement et tous marchait bien.

    Lorsque j'ai copié cette procédure stockée sur le serveur des tests rien ne marche plus.

    Il semble que les deux serveurs n'offrent pas les mêmes permissions.

    Dans ma procédure stockée j'avais créer des tables avec into.

    J'ai aussi vérifé l'existence de table avec :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    IF  NOT EXISTS (SELECT * FROM sysobjects WHERE id = OBJECT_ID('Mabase.dbo.Table_1') AND type IN ('U')) 
      BEGIN
         Print 'Ljhdbjdsbvjhbvfjbvjv' 
      END
    mais ca me donne une réponse que la Table_1 n'existe pas, alors que en réalité la table exite.

    Les deux select suivants suivants donne deux résultats différents. le premier me donne le id et le type alors que le deuxième ne trouve rien.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    SELECT id, type FROM sysobjects WHERE id = OBJECT_ID('Mabase.dbo.Table_1')
    SELECT id, type FROM Master.dbo.sysobjects WHERE id = OBJECT_ID('Mabase.dbo.Table_1')
    Aussi des fois ca me donne "X" comme type et non "U"

    Y a t-il moyen de remédier à ces confusions ?

    Merci.

  2. #2
    Modérateur

    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Janvier 2005
    Messages
    5 826
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2005
    Messages : 5 826
    Points : 12 371
    Points
    12 371
    Par défaut
    Bonjour,

    La fonction OBJECT_ID ne fonctionne que dans le contexte de la base de données actuelle, donc vous ne pouvez pas qualifier le nom de la table par le nom du schéma à laquelle elle appartient, ni par la base de données qui l'héberge.

    Vous pouvez écrire directement :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    IF EXISTS
    (
    	SELECT *
    	FROM sysobjects
    	WHERE name = 'maTable'	
    )
    BEGIN
    	-- Traitement ...
    END
    @++

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    430
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Octobre 2006
    Messages : 430
    Points : 103
    Points
    103
    Par défaut
    Citation Envoyé par elsuket Voir le message
    Bonjour,

    La fonction OBJECT_ID ne fonctionne que dans le contexte de la base de données actuelle, donc vous ne pouvez pas qualifier le nom de la table par le nom du schéma à laquelle elle appartient, ni par la base de données qui l'héberge.

    Vous pouvez écrire directement :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    IF EXISTS
    (
        SELECT *
        FROM sysobjects
        WHERE name = 'maTable'    
    )
    BEGIN
        -- Traitement ...
    END
    @++
    Merci Elsuket je vais l'essayer lundi.
    Est-ce que ca serait possible que ce serveur n'accepte pas la création de table avec la clause " into" mais plutôt des tables temporaires avec précédé par le signe % ou # ?

  4. #4
    Modérateur

    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Janvier 2005
    Messages
    5 826
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2005
    Messages : 5 826
    Points : 12 371
    Points
    12 371
    Par défaut
    Je vous déconseille la création de tables dans vos procédures stockées à l'aide de la clause INTO de l'instruction SELECT.
    Même chose pour les tables temporaires

    @++

  5. #5
    Membre régulier
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    430
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Octobre 2006
    Messages : 430
    Points : 103
    Points
    103
    Par défaut
    Citation Envoyé par elsuket Voir le message
    Je vous déconseille la création de tables dans vos procédures stockées à l'aide de la clause INTO de l'instruction SELECT.
    Même chose pour les tables temporaires

    @++
    Ma procédure stockée est exécutée par une job la nuit et elle s'exécute une fois par jour.

    Dans ce cas, devrais-je créer mes tables temporaires moi même et les effacer à la fin de la procédure stockée ou bien utiliser des tables temporaires du systèmes qui seront effaçées automatiquement.

    tables temporaires
    SQL Server permet de stocker dans des variables table ou des tables temporaires (locales à la session ou globales à l'instance) des données.
    Puis laquelle dois-je utilisée ? locale à la session ou bien globales à l'instance ?

    Merci.

  6. #6
    Membre régulier
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    430
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Octobre 2006
    Messages : 430
    Points : 103
    Points
    103
    Par défaut
    Citation Envoyé par DEV-10 Voir le message
    Merci Elsuket je vais l'essayer lundi.
    Est-ce que ca serait possible que ce serveur n'accepte pas la création de table avec la clause " into" mais plutôt des tables temporaires avec précédé par le signe % ou # ?
    Je viens de l'essayer comme suit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    SELECT *
        FROM sysobjects
        WHERE name = 'maTable'
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    SELECT *
        FROM sysobjects
        WHERE name = 'maBase.dbo.maTable'
    Ca marche lorsque dans l'analyseur de requête je suis insatllé sur la bases de données où se trouve matable.

    Mais ca ne marche pas lorsque je suis installé sur une autre bases de données.

    Mais puisque ma procédure stockée fait appel à des tables dans différentes bases de données comment faut-il faire pour tester l'existence des tables dans plusieurs bases données ?

    Merci.

  7. #7
    Membre régulier
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    430
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Octobre 2006
    Messages : 430
    Points : 103
    Points
    103
    Par défaut
    Citation Envoyé par DEV-10 Voir le message
    Je viens de l'essayer comme suit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    SELECT *
        FROM sysobjects
        WHERE name = 'maTable'
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    SELECT *
        FROM sysobjects
        WHERE name = 'maBase.dbo.maTable'
    Ca marche lorsque dans l'analyseur de requête je suis insatllé sur la bases de données où se trouve matable.

    Mais ca ne marche pas lorsque je suis installé sur une autre bases de données.

    Mais puisque ma procédure stockée fait appel à des tables dans différentes bases de données comment faut-il faire pour tester l'existence des tables dans plusieurs bases données ?

    Merci.
    Je peux rajouter avant chaque test d'existence de table l'énonçé suiavnt
    Mais je ne pense pas que c'est la meilleure solution.

  8. #8
    Modérateur

    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Janvier 2005
    Messages
    5 826
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2005
    Messages : 5 826
    Points : 12 371
    Points
    12 371
    Par défaut
    Tu peux écrire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT *
    FROM maBase.sys.sysobjects
    WHERE name = 'maTable'
    @++

  9. #9
    Membre régulier
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    430
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Octobre 2006
    Messages : 430
    Points : 103
    Points
    103
    Par défaut
    Citation:
    Envoyé par elsuket
    Je vous déconseille la création de tables dans vos procédures stockées à l'aide de la clause INTO de l'instruction SELECT.
    Même chose pour les tables temporaires

    @++
    Ma procédure stockée est exécutée par une job la nuit et elle s'exécute une fois par jour.

    Dans ce cas, devrais-je créer mes tables temporaires moi même et les effacer à la fin de la procédure stockée ou bien utiliser des tables temporaires du systèmes qui seront effaçées automatiquement.

    Citation:
    tables temporaires
    SQL Server permet de stocker dans des variables table ou des tables temporaires (locales à la session ou globales à l'instance) des données.
    Puis laquelle dois-je utilisée ? locale à la session ou bien globales à l'instance ?
    Merci.

  10. #10
    Modérateur

    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Janvier 2005
    Messages
    5 826
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2005
    Messages : 5 826
    Points : 12 371
    Points
    12 371
    Par défaut
    Ma procédure stockée est exécutée par une job la nuit et elle s'exécute une fois par jour.

    Dans ce cas, devrais-je créer mes tables temporaires moi même et les effacer à la fin de la procédure stockée ou bien utiliser des tables temporaires du systèmes qui seront effacées automatiquement.
    Alors pourquoi les effacer ? Que vont-elle gêner ? Il vous suffit de les tronquer en fin de traitement (TRUNCATE TABLE dbo.maTable)
    Notez que lorsque vous inscrivez dans une procédure stockée une commande DDL telle que CREATE TALE et /ou DROP TABLE, SQL Server ne peut pas optimiser le plan, puisque ces tables n'existent pas.
    Cela aboutit donc à la recompilation des requêtes qui sont entre ces deux instructions, ce qui n'est pas souhaitable, même si nos traitements sont effectués à une heure de faible utilisation de la base de données.

    Vous pouvez en plus profiter de l'indexation sans jouer dans le "bac-à-sable" de SQL Server qu'est TempDB
    TempDB est une base de données système, et à ce titre vous ne devez pas effectuer vos traitements dans l'une de ces bases de données : les bases de données utilisateurs sont là pour ça, et SQL Server sait très bien les gérer , mais pour cela il faut le laisser tranquille, donc ne pas toucher aux bases de données système.

    Puis laquelle dois-je utilisée ? locale à la session ou bien globales à l'instance ?
    Aucune des deux
    S'il vous semble difficile de vous en passer, détaillez-nous ce que vous devez faire, je suis certain que nous trouverons une bonne solution

    @++

  11. #11
    Membre régulier
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    430
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Octobre 2006
    Messages : 430
    Points : 103
    Points
    103
    Par défaut
    Citation Envoyé par elsuket Voir le message
    Alors pourquoi les effacer ? Que vont-elle gêner ? Il vous suffit de les tronquer en fin de traitement (TRUNCATE TABLE dbo.maTable)
    C'est quoi la diférence entre Truncate et delete ? moi je les vide au besoin avec delete.

    Citation Envoyé par elsuket Voir le message
    Notez que lorsque vous inscrivez dans une procédure stockée une commande DDL telle que CREATE TALE et /ou DROP TABLE, SQL Server ne peut pas optimiser le plan, puisque ces tables n'existent pas.
    Cela aboutit donc à la recompilation des requêtes qui sont entre ces deux instructions, ce qui n'est pas souhaitable, même si nos traitements sont effectués à une heure de faible utilisation de la base de données.
    Citation Envoyé par elsuket Voir le message
    Aucune des deux
    S'il vous semble difficile de vous en passer, détaillez-nous ce que vous devez faire, je suis certain que nous trouverons une bonne solution

    @++
    Comment fait-on alors pour créer des tables temporaires utilisateurs dont on aura besoin juste durant l'éxécution de la job ?


    Ce qui arrive c'est lorsque je crée des tables et je les supprime en fin de traitement, si jamais pour une raison quelconque la procédure ne s'exécute pas complètement et elle avorte, c'est tables que j'avais créer en mi-parcours vont rester là.

    Même si je fais un test de leur existence avant de les créer, il y a d'autres contraintes sur un serveur qui est utilisé par plus que 300 développeurs, car si on ouvre la porte à tous les développeurs de créer leur propres tables pour une raison XYZ, on se retrouverait avec une base de données pleine de table inconnues et sa maintenance deviendra plus difficle. Qu'est ce que tu en penses ?

  12. #12
    Modérateur

    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Janvier 2005
    Messages
    5 826
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2005
    Messages : 5 826
    Points : 12 371
    Points
    12 371
    Par défaut
    C'est quoi la diférence entre Truncate et delete ? moi je les vide au besoin avec delete.
    TRUNCATE TABLE utilise moins les ressources du fichier du journal des transactions : DELETE supprime les lignes une à une, et enregistre dans le fichier du journal des transactions toutes les données pour chaque ligne supprimée.
    TRUNCATE TABLE supprime les données de la table par désallocation des pages de données, et n'enregistre donc que les désallocations de pages dans le fichier du journal des transactions.
    De ce fait, TRUNCATE TABLE utilise donc moins de verrous qu'une instruction DELETE (verrou de ligne), alors que TRUNCATE TABLE utilisera un verrou de table.

    Comment fait-on alors pour créer des tables temporaires utilisateurs dont on aura besoin juste durant l'exécution de la job ?
    Pourquoi voulez-vous les recréer alors que vous allez devoir les utiliser tous les jours ? Créez-les et laissez-les !

    il y a d'autres contraintes sur un serveur qui est utilisé par plus que 300 développeurs, car si on ouvre la porte à tous les développeurs de créer leur propres tables pour une raison XYZ, on se retrouverait avec une base de données pleine de table inconnues et sa maintenance deviendra plus difficle. Qu'est ce que tu en penses ?
    Je suis d'accord avec toi, mais entre créer des tables d'import et pourrir un schéma de bases de données de tables qui ne servent à rien, il y a une différence. Tu peux tout à fait implémenter le processus d'import en conservant ces tables dans le schéma, puis les supprimer de cet environnement de développement dès que cela sera terminé et que tu devras porter ton implémentation en production.
    Tu peux aussi choisir de séparer ces tables du schéma par défaut (CREATE SCHEMA Import AUTHORIZATION dbo, par exemple), pour bien marquer la différence entre les tables qui sont utilisées pour les transactions temps réel des modifications de données que tu souhaites faire en aparté.

    A mon sens créer des tables d'import, c'est comme créer une table de dates, de nombres (§3), de couleurs, ... : ça n'a rien à voir avec le schéma de données du métier, mais c'est tellement mieux de les avoir

    @++

  13. #13
    Membre régulier
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    430
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Octobre 2006
    Messages : 430
    Points : 103
    Points
    103
    Par défaut
    Citation Envoyé par elsuket Voir le message
    Pourquoi voulez-vous les recréer alors que vous allez devoir les utiliser tous les jours ? Créez-les et laissez-les !

    @++
    Non je ne vais pas les utiliser tous les jours.
    Ces tables je les crée pour y mettre des données temporaires seulement.

    Lorsque j'ai un gros traitement à faire, au lieu de faire des requêtes imbriquées l'une dans l'autre, je sépare ces requêtes et je mets le résultat dans une table X, puis lorsque je veux faire la requête suivante, je repars de la table X et je crée la table Y, et ainsi de suite.
    à la fin de la procédure, je supprime toutes les Tables X, Y, ... qui m'ont servi à stoker temporairement mes données.

    Je ne sais pas si c'est plus clair pour toi maintenant. Si oui, faut-il alors créer ces tables temporaires avec le symbole # ou ## ?

    Si oui, durant la période de test (avant d'aller en production) en cas des erreurs, je n'aurais pas accès à ces tables pour aller voir leurs contenus afin de retracer l'origine de l'erreur.

  14. #14
    Modérateur

    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Janvier 2005
    Messages
    5 826
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2005
    Messages : 5 826
    Points : 12 371
    Points
    12 371
    Par défaut
    Non je ne vais pas les utiliser tous les jours.
    Ces tables je les crée pour y mettre des données temporaires seulement.
    Je ne sais pas si c'est plus clair pour toi maintenant. Si oui, faut-il alors créer ces tables temporaires avec le symbole # ou ## ?
    OK là je comprends ta démarche.
    Mais je reste convaincu que jouer avec les bases de données système n'est pas bon, et donc que tu ne devrais pas créer des tables temporaires.

    Je te conseille plutôt d'écrire une procédure stockée pour créer les tables, et une autre pour les supprimer, ou encore une procédure stockée qui prend un BIT en entrée et qui suivant la valeur de celui-ci, crée ou supprime les tables :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    CREATE PROCEDURE ps_CreeSupprimeTable
    	@creeTable BIT
    AS
    BEGIN
    	IF @creeTable = 1
    	BEGIN
    		CREATE TABLE dbo.Table1
    		(
    			colonnesDeTable1
    		)
     
    		CREATE TABLE dbo.Table2
    		(
    			colonnesDeTable2
    		)
     
    		CREATE TABLE dbo.TableX
    		(
    			colonnesDeTableX
    		)
     
    		CREATE TABLE dbo.TableN
    		(
    			colonnesDeTableN
    		)
    	END
    	ELSE
    	BEGIN
    		DROP TABLE dbo.Table1
    		DROP TABLE dbo.Table2
    		DROP TABLE dbo.TableX
    		DROP TABLE dbo.TableN
    	END
    END
    Tu peux ainsi les appeler dans la procédure stockée qui fait :

    au lieu de faire des requêtes imbriquées l'une dans l'autre, je sépare ces requêtes et je mets le résultat dans une table X, puis lorsque je veux faire la requête suivante, je repars de la table X et je crée la table Y, et ainsi de suite.
    De cette façon, tu n'auras pas les problèmes de recompilation

    @++

  15. #15
    Membre régulier
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    430
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Octobre 2006
    Messages : 430
    Points : 103
    Points
    103
    Par défaut
    Citation Envoyé par elsuket Voir le message
    OK là je comprends ta démarche.
    Mais je reste convaincu que jouer avec les bases de données système n'est pas bon, et donc que tu ne devrais pas créer des tables temporaires.

    Je te conseille plutôt d'écrire une procédure stockée pour créer les tables, et une autre pour les supprimer, ou encore une procédure stockée qui prend un BIT en entrée et qui suivant la valeur de celui-ci, crée ou supprime les tables :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    CREATE PROCEDURE ps_CreeSupprimeTable
        @creeTable BIT
    AS
    BEGIN
        IF @creeTable = 1
        BEGIN
            CREATE TABLE dbo.Table1
            (
                colonnesDeTable1
            )
     
            CREATE TABLE dbo.Table2
            (
                colonnesDeTable2
            )
     
            CREATE TABLE dbo.TableX
            (
                colonnesDeTableX
            )
     
            CREATE TABLE dbo.TableN
            (
                colonnesDeTableN
            )
        END
        ELSE
        BEGIN
            DROP TABLE dbo.Table1
            DROP TABLE dbo.Table2
            DROP TABLE dbo.TableX
            DROP TABLE dbo.TableN
        END
    END
    Tu peux ainsi les appeler dans la procédure stockée qui fait :


    De cette façon, tu n'auras pas les problèmes de recompilation

    @++
    Si je comprends bien, tu prèfere faire la création de tables et les supprimer à la fin, que créer des tables temporaires avec # ou ## ? est-ce bien ça ?

    Qu'est ce qui arrive si pour une raison imprévue, la procédure stokée ne s'exécute pas complétement ? les tables qui ont été crée jusqu'à ce que la panne arrive, vont rester dans la bases données.

    Quels seront tes arguments pour justifier ce choix ?

    Merci.

  16. #16
    Modérateur

    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Janvier 2005
    Messages
    5 826
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2005
    Messages : 5 826
    Points : 12 371
    Points
    12 371
    Par défaut
    Si je comprends bien, tu prèfere faire la création de tables et les supprimer à la fin, que créer des tables temporaires avec # ou ## ? est-ce bien ça ?
    C'est exact.

    Qu'est ce qui arrive si pour une raison imprévue, la procédure stokée ne s'exécute pas complétement ? les tables qui ont été crée jusqu'à ce que la panne arrive, vont rester dans la bases données.

    Quels seront tes arguments pour justifier ce choix ?
    Les instructions de création et de suppression des tables étant encapsulées dans une transaction, si l'on déclare une transaction de façon explicite que que l'une des instructions échoue, il suffit de défaire la transaction pour voir l'ensemble ds tables être supprimées.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    BEGIN TRAN maTransaction
    	CREATE TABLE dbo.A
    	(
    		valA INT
    	)
     
    	CREATE TABLE dbo.B
    	(
    		valB INT
    	)
    ROLLBACK TRANSACTION maTransaction
    Si tu exécutes ce bout de code, tu verras que ni la table A ni la table B ne demeurent dans la base de données.

    C'est vrai que je ne t'ai pas proposé le code de cette façon, et tu as eu raison de poser cette question.

    Dès lors la petite procédure que je t'ai proposé devrait être :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    CREATE PROCEDURE ps_CreeSupprimeTable
        @creeTable BIT
    AS
    BEGIN
    	DECLARE @errMsg NVARCHAR(2048)
     
        IF @creeTable = 1
        BEGIN
    		BEGIN TRY
    			BEGIN TRANSACTION creationTable
            		CREATE TABLE dbo.Table1
            		(
            			colonnesDeTable1
           			)
     
    				CREATE TABLE dbo.Table2
            		(
            			colonnesDeTable2
            		)
     
            		CREATE TABLE dbo.TableX
           			(
                		colonnesDeTableX
            		)
     
    				CREATE TABLE dbo.TableN
    				(
    					colonnesDeTableN
    				)
    			COMMIT TRANSACTION creationTable
    		END TRY
    		BEGIN CATCH			
    			SELECT @errMsg = ERROR_MESSAGE()
     
    			ROLLBACK TRANSACTION creationTable
     
    			RAISERROR(@errMsg, 16, 1)
    		END CATCH
        END
        ELSE
        BEGIN
    		BEGIN TRY
    			BEGIN TRANSACTION supprimeTable
    				DROP TABLE dbo.Table1
    				DROP TABLE dbo.Table2
    				DROP TABLE dbo.TableX
    				DROP TABLE dbo.TableN
    			COMMIT TRANSACTION supprimeTable
    		END TRY
    		BEGIN CATCH
    			SELECT @errMsg = ERROR_MESSAGE()
     
    			ROLLBACK TRANSACTION creationTable
     
    			RAISERROR(@errMsg, 16, 1)
    		END CATCH
        END
    END
    Si on créait les tables dans TempDB et que l'un des instructions échouait, alors on laisserait SQL Server supprimer cette table temporaire alors qu'il a bien d'autres chats à fouetter .

    Cela ne me dérange pas de le répéter : TempDB n'est pas une base de données utilisateur, donc on ne doit pas avoir recours à son utilisation.

    Si on peut guider le moteur de base de données dans ses choix d'optimisation de requête, il ne faut pas oublier que SQL est un langage déclaratif, donc ce n'est pas à l'utilisateur de dicter au moteur de base de données où et comment il doit stocker les données : il sait très bien le faire tout seul

    @++

  17. #17
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 21 761
    Points : 52 544
    Points
    52 544
    Billets dans le blog
    5
    Par défaut
    Citation Envoyé par DEV-10 Voir le message
    Lorsque j'ai un gros traitement à faire, au lieu de faire des requêtes imbriquées l'une dans l'autre, je sépare ces requêtes et je mets le résultat dans une table X, puis lorsque je veux faire la requête suivante, je repars de la table X et je crée la table Y, et ainsi de suite.
    à la fin de la procédure, je supprime toutes les Tables X, Y, ... qui m'ont servi à stoker temporairement mes données.
    C'est la manière la plus catastrophique de faire la chose en terme de performan ces. Si vous voulez sciemment pourrir les performances de votre système, alors continuez comme cela, amusez vous avec des tables temporaires.
    EEn revanche si vous voulez être rapide et efficace, il suffit de ne faire qu'une seule grosse requête imbriquée...
    Lisez l'article que j'ai écrit sur les tables temporaires : http://blog.developpez.com/sqlpro/p6...t-persistance/
    En ne faisant qu'une seule grosse requête, vous éviterez toutes les opérations de disque et toutes les recompilations... sur un fort volume de données, vous pouvez aller jusqu'à 1000 fois plus vite !

    A +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *

  18. #18
    Membre régulier
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    430
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Octobre 2006
    Messages : 430
    Points : 103
    Points
    103
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    CREATE PROCEDURE ps_CreeSupprimeTable
        @creeTable BIT
    AS
    BEGIN
        DECLARE @errMsg NVARCHAR(2048)
     
        IF @creeTable = 1
        BEGIN
            BEGIN TRY
                BEGIN TRANSACTION creationTable
                    CREATE TABLE dbo.Table1
                    (
                        colonnesDeTable1
                       )
     
                    CREATE TABLE dbo.Table2
                    (
                        colonnesDeTable2
                    )
     
                    CREATE TABLE dbo.TableX
                       (
                        colonnesDeTableX
                    )
     
                    CREATE TABLE dbo.TableN
                    (
                        colonnesDeTableN
                    )
                COMMIT TRANSACTION creationTable
            END TRY
            BEGIN CATCH            
                SELECT @errMsg = ERROR_MESSAGE()
     
                ROLLBACK TRANSACTION creationTable
     
                RAISERROR(@errMsg, 16, 1)
            END CATCH
        END
        ELSE
        BEGIN
            BEGIN TRY
                BEGIN TRANSACTION supprimeTable
                    DROP TABLE dbo.Table1
                    DROP TABLE dbo.Table2
                    DROP TABLE dbo.TableX
                    DROP TABLE dbo.TableN
                COMMIT TRANSACTION supprimeTable
            END TRY
            BEGIN CATCH
                SELECT @errMsg = ERROR_MESSAGE()
     
                ROLLBACK TRANSACTION creationTable
     
                RAISERROR(@errMsg, 16, 1)
            END CATCH
        END
    END
    Oui maintenant ça répond bien à mon besoin. Un grand merci.

    En passant, pour ma procédure actuelle qui est déjà écrite et que mes tables ont été créer au fur et à mesure, est-ce que ça serait possible de prendre toute la procédure au complet et l'encapsuler dans une transaction

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
     
    BEGIN
            BEGIN TRY
                BEGIN TRANSACTION maprocedure
                   -- contenu de ma procédure
               COMMIT TRANSACTION creationTable
            END TRY
            BEGIN CATCH            
                SELECT @errMsg = ERROR_MESSAGE()
     
                ROLLBACK TRANSACTION creationTable
     
                RAISERROR(@errMsg, 16, 1)
            END CATCH
        END
        ELSE
        BEGIN
            BEGIN TRY
                BEGIN TRANSACTION supprimeTable
                    DROP TABLE dbo.Table1
                    DROP TABLE dbo.Table2
                    DROP TABLE dbo.TableX
                    DROP TABLE dbo.TableN
                COMMIT TRANSACTION supprimeTable
            END TRY
            BEGIN CATCH
                SELECT @errMsg = ERROR_MESSAGE()
     
                ROLLBACK TRANSACTION creationTable
     
                RAISERROR(@errMsg, 16, 1)
            END CATCH
        END
    END

  19. #19
    Membre régulier
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    430
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Octobre 2006
    Messages : 430
    Points : 103
    Points
    103
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    CREATE PROCEDURE ps_CreeSupprimeTable
        @creeTable BIT
    AS
    BEGIN
        DECLARE @errMsg NVARCHAR(2048)
     
        IF @creeTable = 1
        BEGIN
            BEGIN TRY
                BEGIN TRANSACTION creationTable
                    CREATE TABLE dbo.Table1
                    (
                        colonnesDeTable1
                       )
     
                    CREATE TABLE dbo.Table2
                    (
                        colonnesDeTable2
                    )
     
                    CREATE TABLE dbo.TableX
                       (
                        colonnesDeTableX
                    )
     
                    CREATE TABLE dbo.TableN
                    (
                        colonnesDeTableN
                    )
                COMMIT TRANSACTION creationTable
            END TRY
            BEGIN CATCH            
                SELECT @errMsg = ERROR_MESSAGE()
     
                ROLLBACK TRANSACTION creationTable
     
                RAISERROR(@errMsg, 16, 1)
            END CATCH
        END
        ELSE
        BEGIN
            BEGIN TRY
                BEGIN TRANSACTION supprimeTable
                    DROP TABLE dbo.Table1
                    DROP TABLE dbo.Table2
                    DROP TABLE dbo.TableX
                    DROP TABLE dbo.TableN
                COMMIT TRANSACTION supprimeTable
            END TRY
            BEGIN CATCH
                SELECT @errMsg = ERROR_MESSAGE()
     
                ROLLBACK TRANSACTION creationTable
     
                RAISERROR(@errMsg, 16, 1)
            END CATCH
        END
    END
    Oui maintenant ça répond bien à mon besoin. Un grand merci.

    En passant, pour ma procédure actuelle qui est déjà écrite et que mes tables ont été déjà créer au fur et à mesure, est-ce que ça serait possible de prendre toute la procédure au complet et l'encapsuler dans une transaction de ce genre ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     
    BEGIN
            BEGIN TRY
                BEGIN TRANSACTION maprocedure
                       -- contenu de ma procédure
               COMMIT TRANSACTION creationTable
            END TRY
            BEGIN CATCH            
                SELECT @errMsg = ERROR_MESSAGE()
     
                ROLLBACK TRANSACTION maprocedure
     
                RAISERROR(@errMsg, 16, 1)
            END CATCH
    END

  20. #20
    Membre régulier
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    430
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Octobre 2006
    Messages : 430
    Points : 103
    Points
    103
    Par défaut
    Citation Envoyé par SQLpro Voir le message
    C'est la manière la plus catastrophique de faire la chose en terme de performan ces. Si vous voulez sciemment pourrir les performances de votre système, alors continuez comme cela, amusez vous avec des tables temporaires.
    EEn revanche si vous voulez être rapide et efficace, il suffit de ne faire qu'une seule grosse requête imbriquée...
    Pour faire une seule requête imbriquée, ca serait très pénible à maintenir par les futurs développeurs.

    Par curiosité, j'ai fais un test de performance avec une table de 3000 lignes et le tout s'éxécute en 21 secondes. J'ai refais le test avec une table de 800 000 lignes et le temps de réponse était de 25 secondes (4 secondes de plus). Bien-sûr je ne parle que du temps de réponse et non de toutes les autres ressources qui ont été utilisées.
    Pour 4 secondes de plus, pour une job qui s'éxécute le soir c'est négligeable et le code reste lisible et facile à maintenir.

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. boucle sur les dossiers et conacténatenation des tables
    Par Mery_Dau88 dans le forum Macros Access
    Réponses: 0
    Dernier message: 04/09/2014, 10h16
  2. Etablir des modifs sur les permissions sur serveur FREE
    Par dessinateurttuyen dans le forum Outils
    Réponses: 5
    Dernier message: 02/04/2008, 16h46
  3. Conditions sur les champs d'une même table
    Par Pucho dans le forum Modélisation
    Réponses: 10
    Dernier message: 19/10/2007, 17h52
  4. Requete sur les elements d'une même table
    Par jean-marieb dans le forum Langage SQL
    Réponses: 2
    Dernier message: 18/10/2007, 14h40
  5. Réponses: 4
    Dernier message: 01/08/2007, 17h22

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo