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

MS SQL Server Discussion :

Problème avec procédure stockée appelée via dblink


Sujet :

MS SQL Server

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Février 2010
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2010
    Messages : 5
    Points : 5
    Points
    5
    Par défaut Problème avec procédure stockée appelée via dblink
    Bonjour,

    J'ai un problème assez étonnant avec une procédure stockée SQL-Server appelée depuis oracle via un dblink.

    Les données du problème :
    Je crée une table TEST :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    CREATE TABLE TEST (TEXTE nvarchar(50))
    INSERT INTO TEST (TEXTE) VALUES ('ABCD')
    Je crée une procédure qui me renvoie la table TEST
    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
    CREATE PROCEDURE [dbo].[TESTPROC]
    	@aParam Int
    AS
    BEGIN
    	-- SET NOCOUNT ON added to prevent extra result sets from
    	-- interfering with SELECT statements.
    	SET NOCOUNT ON;
     
        if @aParam = 1 
          -- si param=1 renvoie la table TEST
      	  select TEXTE from dbo.TEST
        else
          -- Sinon renvoie un code d'erreur -1
      	  select '-1' as TEXTE
    END
    Tout ça fonctionne bien sûr très bien sous SQL-Server

    Là où c'est moins drôle c'est quand j'appelle la procédure depuis Oracle via un dblink :
    Si j'appelle la procédure en lui passant aParam=0 elle me renvoie bien "-1" comme prévu
    Si je l'appelle en lui passant 1 j'ai le message d'erreur :
    [Generic Connectivity Using ODBC][Microsoft][ODBC SQL Server Driver]
    Erreur sur la ligne[Microsoft][ODBC SQL Server Driver]
    Troncation à droite de la chaîne de données
    Je modifie la procédure stockée en inversant simplement le IF:
    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
    ALTER PROCEDURE [dbo].[TESTPROC]
    	@aParam Int
    AS
    BEGIN
    	-- SET NOCOUNT ON added to prevent extra result sets from
    	-- interfering with SELECT statements.
    	SET NOCOUNT ON;
     
        if @aParam != 1 
          -- Sinon renvoie un code d'erreur -1
      	  select '-1' as TEXTE
        else
          -- si param=1 renvoie la table TEST
      	  select TEXTE from dbo.TEST
    END
    Là plus de problème, ça fonctionne dans tous les cas.

    Sinon j'ai essayé ça qui fonctionne également dans tous les cas :
    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
    ALTER PROCEDURE [dbo].[TESTPROC]
    	@aParam Int
    AS
    BEGIN
    	-- SET NOCOUNT ON added to prevent extra result sets from
    	-- interfering with SELECT statements.
    	SET NOCOUNT ON;
     
        if @aParam = 1 
          -- si param=1 renvoie la table TEST
      	  select TEXTE from dbo.TEST
        else
          -- Sinon renvoie un code d'erreur -1
      	  select '-1' as TEXTE
      -- Code jamais éxécuté mais qui évite le message d'erreur
      if 1=2 select 'xxxxxxxxxxxxxxxxxxxx'  
    END
    Si si je vous assure je ne fume pas et d'ailleurs je n'ai pas de moquette dans le bureau.
    Il faut que le nombre de caractères dans le "if 1=2 select 'xxxxxxxxxxxxxx'" soit plus grand que la plus grande chaine de la table TEST.

    Quelqu'un peut m'expliquer le fonctionnement de SQL-Server ? J'ai l'impression que le code est interpreté au runtime et qu'il se base sur le dernier select pour déterminer la taille du buffer (d'où le message d'erreur "troncation à droite") ?

    Il est difficile de livrer un code "sérieux" en expliquant qu'il ne faut surtout pas inverser le sens des "if else" ou en ajoutant des "if 1=2" !

    Merci.

    Pour info j'ai mis le code de la procédure oracle :
    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
    create or replace TYPE TTEST  IS OBJECT (STR1 VARCHAR2(50));
    /
    create or replace TYPE TEST_SET AS TABLE OF TTEST;
    /
    create or replace function TEST (aParam in Integer) return TEST_SET pipelined as
      lRec  TTEST;           -- Record resultat
      c Integer;             -- Handle de curseur  
      lReqSql VarChar2(200); -- Requète SqlServer
      i Integer;
    begin
      lRec := TTEST('');
      -- Crée un curseur pour requète dans SqlServer via HS 
      c := DBMS_HS_PASSTHROUGH.OPEN_CURSOR@DBLINK;
      -- Construit la requète
      lReqSQl:='EXEC TESTPROC '||to_char(aParam);
      -- execution
      DBMS_HS_PASSTHROUGH.PARSE@DBLINK(c, lreqSql);
      --recuperation des données
      loop
        -- Lecture d'un enregistrement
        i:=DBMS_HS_PASSTHROUGH.FETCH_ROW@DBLINK(c, False);
        exit when I=0; -- EOF si i=0
        DBMS_HS_PASSTHROUGH.GET_VALUE@DBLINK(c,1,lRec.Str1);
        pipe row (lRec);
      end loop;
      DBMS_HS_PASSTHROUGH.CLOSE_CURSOR@DBLINK(c);
    end;
    /
    -- appel de la fonction
    select * from table(Test(1));

  2. #2
    Membre expérimenté

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Septembre 2003
    Messages
    733
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2003
    Messages : 733
    Points : 1 668
    Points
    1 668
    Billets dans le blog
    8
    Par défaut
    Je te suggère, pour éviter (ou limiter) au maximum les problèmes et erreurs, de procéder ainsi :

    1 – Respecter les correspondances (ou mappage) des types Oracle /Sql Server
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Oracle             SQL Server 
    VARCHAR2([1-4000])    VARCHAR([1-4000] 
    NVARCHAR2([1-2000]) 	NVARCHAR([1-2000])
    Or comme sous Oracle, la propriété STR1 est de type VARCHAR2(50), le type correspondant sous SQL Server est VARCHAR(50) (et non pas NVARCHAR(50))?

    2 – De faire en sorte que, dans la procédure SQL Server dbo.TESTPROC le type de la colonne TEXTE soit toujours le même et ce quel que soit le test effectué sur le paramètre @aParam. Pour cela, il faut « caster » la constante -1 en varchar(50)
    Conclusion je te propose de tester la solution ci-dessous :

    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
    CREATE TABLE TEST (TEXTE VARCHAR(50))    -- et non pas nvarchar(50) 
     
    INSERT INTO TEST (TEXTE) VALUES ('ABCD')
     
    CREATE PROCEDURE [dbo].[TESTPROC]
    	@aParam Int
    AS
    BEGIN
    	-- SET NOCOUNT ON added to prevent extra result sets from
    	-- interfering with SELECT statements.
    	SET NOCOUNT ON;
     
        IF @aParam = 1 
          -- si param=1 renvoie la table TEST
      	  SELECT CAST(TEXTE AS VARCHAR(50)) FROM dbo.TEST    -- (1) 
        ELSE
          -- Sinon renvoie un code d'erreur -1
      	  SELECT CAST('-1' AS VARCHAR(50)) AS TEXTE
    END
    -- (1) si TEXTE est de type VARCHAR(50), un SELECT TEXTE FROM dbo.TEST aurait suffit sans le CAST, mais si pour une raison ou une autre le type du champ TEXTE doit être différent, il vaudrait mieux garder le CAST.

    A+

  3. #3
    Futur Membre du Club
    Profil pro
    Inscrit en
    Février 2010
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2010
    Messages : 5
    Points : 5
    Points
    5
    Par défaut
    Bonjour hmira,

    Merci pour ta réponse.
    J'ai essayé avec le
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT CAST('-1' AS VARCHAR(50)) AS TEXTE
    ça fonctionne bien, plus de problème.

    Pour info j'ai essayé en mixant les VarChar et NVarChar ça marche dans tous les cas.

    Encore merci.

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

Discussions similaires

  1. [2008] Problème avec procédure stockée
    Par djelloharmel dans le forum MS SQL Server
    Réponses: 3
    Dernier message: 22/02/2013, 09h52
  2. problème avec procédure stockée
    Par doudou8mc dans le forum Développement
    Réponses: 8
    Dernier message: 08/10/2009, 18h06
  3. problème avec procédure stockée
    Par kanebody dans le forum SQL Procédural
    Réponses: 1
    Dernier message: 04/08/2009, 13h55
  4. Réponses: 1
    Dernier message: 10/10/2008, 10h50
  5. Réponses: 1
    Dernier message: 17/07/2006, 17h08

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