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 :

Comment coder une requete dynamique avec une Variable binaire.


Sujet :

Développement SQL Server

  1. #1
    Membre régulier
    Profil pro
    DSI
    Inscrit en
    Mars 2009
    Messages
    102
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : DSI

    Informations forums :
    Inscription : Mars 2009
    Messages : 102
    Points : 73
    Points
    73
    Par défaut Comment coder une requete dynamique avec une Variable binaire.
    Bonjour à tous.

    Je dois tester une variable binaire dans une requete dynamique, et je n'arrive pas à trouver de solution.

    Un exemple:
    /* Soit une table ERP, disposant d'un champ appelé Colonne_Timestamp de type Time Stamp.
    Je dois l'historiser dans une table Datamart au format presque identique.
    Dans cette table datamart le champ Colonne_Timestamp de type BINARY(8).
    */

    @company --> contient un code société passé en parametre de la ProcSto.

    Declare @Maximum as binary(8)
    Declace @Requete as varchar(max)

    -- Je détermine le TimeStamp maximum de la table datamart.
    Set @Maximum = (select max(colonne_timestamp) from table_datamart

    -- Je récupère dans ERP tous les Time Stamp supérieurs à @Maximum
    Set @Requete = 'insert into table_datamart select C1, C2, C3, ... '
    + ' from ' + ''' + @company + ''' + '.table_erp '
    + 'where table_erp.colonne_timestamp > ' + @maximum


    Mon probleme se situe au niveau de la clause where!
    le 'where table_erp.colonne_timestamp > ' + @maximum ne passe pas.


    Auriez vous une idée, ou mieux une solution ?

  2. #2
    Expert éminent
    Avatar de Lyche
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Janvier 2007
    Messages
    2 523
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Janvier 2007
    Messages : 2 523
    Points : 6 775
    Points
    6 775
    Billets dans le blog
    4
    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
     
    /* Soit une table ERP, disposant d'un champ appelé Colonne_Timestamp de type Time Stamp.
    Je dois l'historiser dans une table Datamart au format presque identique.
    Dans cette table datamart le champ Colonne_Timestamp de type BINARY(8).
    */
     
    @company --> contient un code société passé en parametre de la ProcSto.
     
    Declare @Maximum as binary(8)
    Declace @Requete as varchar(max)
     
    -- Je détermine le TimeStamp maximum de la table datamart.
    Set @Maximum = (select max(colonne_timestamp) from table_datamart
     
    -- Je récupère dans ERP tous les Time Stamp supérieurs à @Maximum
    Set @Requete = 'insert into table_datamart select C1, C2, C3, ... '
    + ' from ' + ''' + @company + ''' + '.table_erp '
    + 'where table_erp.colonne_timestamp > ' + @maximum


    et pourquoi tu ferais pas une sous requète? au lieu d'avoir une requète qui te remplis ta variable @maximum, pourquoi ne pas faire

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    + 'where table_erp.colonne_timestamp > (select max(colonne_timestamp) from table_datamart)'
    PS : en haut tu as 2 declare. change les en
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    Declare @Maximum as binary(8)
          , @Requete as varchar(max)
    Rejoignez la communauté du chat et partagez vos connaissances ou vos questions avec nous

    Mon Tutoriel pour apprendre les Agregations
    Consultez mon Blog SQL destiné aux débutants

    Pensez à FAQ SQL Server Ainsi qu'aux Cours et Tuto SQL Server

  3. #3
    Membre régulier
    Profil pro
    DSI
    Inscrit en
    Mars 2009
    Messages
    102
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : DSI

    Informations forums :
    Inscription : Mars 2009
    Messages : 102
    Points : 73
    Points
    73
    Par défaut
    Je l 'ai fait bien sur, mais ma proc sto dynamique codée avec un
    (select max(colonne_timestamp) from table_datamart)'
    va drolement plus lentement que quand je travaille avec une requête statique codée comme indiqué.
    J'interprete cette lenteur au fait que la sous requete est évaluée à chaque ligne non ?

  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
    Bonjour,

    Avez-vous essayé en encadrant votre valeur binaire par des quotes ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SET @Requete = 'insert into table_datamart select C1, C2, C3, ... '
    + ' from ' + ''' + @company + ''' + '.table_erp '
    + 'where table_erp.colonne_timestamp > ''' + @maximum + ''
    Dans tous les cas pour savoir ce que vous passez comme requête, utilisez la commande PRINT @Requete avant de l'exécuter

    @++

  5. #5
    Membre régulier
    Profil pro
    DSI
    Inscrit en
    Mars 2009
    Messages
    102
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : DSI

    Informations forums :
    Inscription : Mars 2009
    Messages : 102
    Points : 73
    Points
    73
    Par défaut
    J avais essayé bien sur...
    Message
    The data types varchar and binary are incompatible in the add operator.

  6. #6
    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
    Exact, j'y ai repensé 5 minutes après en me disant qu'avec sp_executeSQL cela doit fonctionner :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    DECLARE @SQL NVARCHAR(256),
    		@ParamDef NVARCHAR(255),
    		@bin BINARY(8)
     
    SELECT @SQL = 'INSERT INTO table_datamart ' +
    			' SELECT C1, C2, C3, ...' +
    			' FROM ' + @company + '.table_erp' +
    			' WHERE colonne_timestamp > @bin',
    		@ParamDef = N'@binIN BINARY(8)',
    		@bin = 0x0000000000000005
     
    EXEC master.dbo.sp_executeSQL @SQL, @ParamDef, @binIN = @bin
    Dites-nous si c'est OK

    @++

  7. #7
    Expert éminent sénior
    Avatar de mikedavem
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Août 2005
    Messages
    5 450
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : Distribution

    Informations forums :
    Inscription : Août 2005
    Messages : 5 450
    Points : 12 891
    Points
    12 891
    Par défaut
    Bonjour,

    Et utilisant la fonction master.dbo.fn_varbintohexstr ? (Voir code ci dessous)
    Edit => En plus de celle proposée par Elsuket

    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
    /* Soit une table ERP, disposant d'un champ appelé Colonne_Timestamp de type Time Stamp.
    Je dois l'historiser dans une table Datamart au format presque identique.
    Dans cette table datamart le champ Colonne_Timestamp de type BINARY(8).
    */
     
    @company --> contient un code société passé en parametre de la ProcSto.
     
    Declare @Maximum AS BINARY(8)
    Declace @Requete AS varchar(max)
     
    -- Je détermine le TimeStamp maximum de la table datamart.
    SELECT @Maximum = max(colonne_timestamp) FROM table_datamart
     
    -- Je récupère dans ERP tous les Time Stamp supérieurs à @Maximum
    SET @Requete = 'insert into table_datamart select C1, C2, C3, ... '
    + ' from ' + @company + '.table_erp '
    + 'where table_erp.colonne_timestamp > ' + master.dbo.fn_varbintohexstr(@maximum)
     
    EXEC(@Requete)
    ++

  8. #8
    Membre régulier
    Profil pro
    DSI
    Inscrit en
    Mars 2009
    Messages
    102
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : DSI

    Informations forums :
    Inscription : Mars 2009
    Messages : 102
    Points : 73
    Points
    73
    Par défaut
    Merci à elsuket et mikedavem.

    Solution de ELSUKET OK.


    Declare @Requete as nvarchar(max)
    Declare @maxim as binary(8)
    Declare @ParamDef as NVARCHAR(500)

    set @maxim = (select max([timestamp]) from [mserveur].[mbase].[dbo].[msociete$G_L Entry])
    Set @requete = 'select * from [mserveur].[mbase].[dbo].[msociete$G_L Entry] '
    + 'where [Timestamp] = @maximum '
    Set @ParamDef = N'@maximum BINARY(8)'

    EXECUTE sp_executeSQL @requete, @ParamDef, @maximum = @maxim

    Solution de mikedavem OK

    Declare @Requete as varchar(max)
    Declare @maxim as binary(8)

    set @maxim = (select max([timestamp]) from [mserveur].[mbase].[dbo].[msociete$G_L Entry])

    Set @requete = 'select * from [mserveur].[mbase].[dbo].[msociete$G_L Entry] '
    + 'where [Timestamp] = ' + master.dbo.fn_varbintohexstr(@maxim)
    Execute (@requete)

  9. #9
    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
    Ceci me conforte dans l'idée de bannir l'utilisation de EXEC(@SQL) pour exécuter du code SQL dynamique :

    - le plan des requêtes exécutées avec sp_executeSQL est conservé, ce qui n'est pas le cas avec EXEC(@SQL)
    - le contexte d'exécution est le même que la procédure appelante lorsqu'on utilise sp_executeSQL, mais pas avec EXEC(@SQL),
    - on peut retourner des valeurs avec sp_executeSQL, ce qui n'est pas possible avec EXEC(@SQL)

    @++

  10. #10
    Expert éminent sénior
    Avatar de mikedavem
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Août 2005
    Messages
    5 450
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : Distribution

    Informations forums :
    Inscription : Août 2005
    Messages : 5 450
    Points : 12 891
    Points
    12 891
    Par défaut
    En terme de performance il est kler qu'il vaut mieux utiliser sp_executsql pour les raisons que tu as cité.

    L'important dans la 2ème solution est simplement de voir qu'il est possible d'utiliser la fonction master.dbo.fn_varbintohexstr()

    ++

  11. #11
    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
    Une fonction intéressante, mais qui n'est pas documentée ...
    A utiliser à nos risques et périls donc

    @++

  12. #12
    Expert éminent sénior
    Avatar de mikedavem
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Août 2005
    Messages
    5 450
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : Distribution

    Informations forums :
    Inscription : Août 2005
    Messages : 5 450
    Points : 12 891
    Points
    12 891
    Par défaut
    Aussi

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 8
    Dernier message: 26/03/2010, 08h16
  2. optimisé une requete SQl avec une requete imbriqués
    Par fabien14 dans le forum Langage SQL
    Réponses: 4
    Dernier message: 16/01/2009, 10h01
  3. Réponses: 4
    Dernier message: 14/11/2008, 20h56
  4. [RegEx] Ecrire une requete INSERT avec des variables $_POST
    Par arnaudperfect dans le forum Langage
    Réponses: 10
    Dernier message: 13/06/2007, 15h12
  5. Comment faire une requete liée avec une requete ?
    Par DavidDeTroyes dans le forum Requêtes
    Réponses: 4
    Dernier message: 18/04/2006, 13h18

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