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

Bases de données Delphi Discussion :

Oracle et Unicode


Sujet :

Bases de données Delphi

  1. #1
    Futur Membre du Club
    Inscrit en
    Juillet 2002
    Messages
    8
    Détails du profil
    Informations forums :
    Inscription : Juillet 2002
    Messages : 8
    Points : 8
    Points
    8
    Par défaut Oracle et Unicode
    Bonjour,
    Je travaille sur un chantier de migration unicode. Je rencontre un souci pour les requêtes avec Oracle : les requêtes utilisant des valeurs unicode ne fonctionnent tout simplement pas. Les valeurs sont remplacées par des points d'interogations à l'envers.
    Le champs sous Oracle est bien en nvarchar2.
    J'ai tenté de mettre le préfixe N devant la valeur : nok.
    Ex : select * from service where libelle = N'會計'
    J'ai tenté de passer par des paramètres : nok.
    Ex : select * from service where libelle = Lib
    Valeur du paramètre : 會計
    J'ai tenté de typer les paramètre en ftwidestring : nok.


    Compilateur : Delphi XE3
    Composant utilisé : DbGo (AdoConnection et AdoQuery)
    Provider : OraOLEDB.Oracle.1 (version 11.2.0.1.0)

    Paramètre de la base de données :
    SELECT * FROM V$NLS_PARAMETERS

    NLS_LANGUAGE FRENCH
    NLS_TERRITORY FRANCE
    NLS_CURRENCY €
    NLS_ISO_CURRENCY FRANCE
    NLS_NUMERIC_CHARACTERS ,
    NLS_CALENDAR GREGORIAN
    NLS_DATE_FORMAT DD/MM/RR
    NLS_DATE_LANGUAGE FRENCH
    NLS_CHARACTERSET WE8MSWIN1252
    NLS_SORT FRENCH
    NLS_TIME_FORMAT HH24:MI:SSXFF
    NLS_TIMESTAMP_FORMAT DD/MM/RR HH24:MI:SSXFF
    NLS_TIME_TZ_FORMAT HH24:MI:SSXFF TZR
    NLS_TIMESTAMP_TZ_FORMAT DD/MM/RR HH24:MI:SSXFF TZR
    NLS_DUAL_CURRENCY €
    NLS_NCHAR_CHARACTERSET AL16UTF16
    NLS_COMP BINARY
    NLS_LENGTH_SEMANTICS BYTE
    NLS_NCHAR_CONV_EXCP FALSE

    SELECT * FROM NLS_SESSION_PARAMETERS

    NLS_LANGUAGE FRENCH
    NLS_TERRITORY FRANCE
    NLS_CURRENCY €
    NLS_ISO_CURRENCY FRANCE
    NLS_NUMERIC_CHARACTERS ,
    NLS_CALENDAR GREGORIAN
    NLS_DATE_FORMAT DD/MM/RR
    NLS_DATE_LANGUAGE FRENCH
    NLS_SORT FRENCH
    NLS_TIME_FORMAT HH24:MI:SSXFF
    NLS_TIMESTAMP_FORMAT DD/MM/RR HH24:MI:SSXFF
    NLS_TIME_TZ_FORMAT HH24:MI:SSXFF TZR
    NLS_TIMESTAMP_TZ_FORMAT DD/MM/RR HH24:MI:SSXFF TZR
    NLS_DUAL_CURRENCY €
    NLS_COMP BINARY
    NLS_LENGTH_SEMANTICS BYTE
    NLS_NCHAR_CONV_EXCP FALSE

    Je ne comprends pas pourquoi cela ne marche pas... si quelqu'un a une piste, je suis preneur.
    Merci d'avance,

  2. #2
    Membre habitué
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2012
    Messages
    92
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2012
    Messages : 92
    Points : 159
    Points
    159
    Par défaut
    salut,

    je suis sur un sujet similaire avec des pb similaires, sauf que je vois le bout du tunnel.

    j'utilise les composants ADO. le code ci-dessous fonctionne à condition d'avoir dans le connectionstring
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    connectionstring = 'Provider=OraOLEDB.Oracle.1;password=...; NDatatype=TRUE;';
    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
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
     
    procedure TfrmMain.Button1Click(Sender: TObject);
    var
      adoquery : TADOQuery ;
    begin
     
      adoquery := TADOQuery.Create(nil);
      try
        try
            adoquery.Connection := dmdConnect.cntMain ;
            adoquery.SQL.Add( 'insert into test_unicode ( TEINT_ID, TEINT_DES_FR, TEINT_DES_RU ) values ( 25 , ''bleu'' ,  N''XXXXX'' )' );
     
            adoquery.ExecSQL ;
     
            ShowMessage( 'Ok' );
     
        except
          on e : Exception do
            ShowMessage( e.Message );
        end;
      finally
        adoquery.Free ;
      end;
     
     
     
     
    end;
     
    procedure TfrmMain.Button2Click(Sender: TObject);
    var
      adoquery : TADOQuery ;
      psValue : string;
      iLen : integer ;
    begin
     
      adoquery := TADOQuery.Create(nil);
      try
        try
            adoquery.Connection := dmdConnect.cntMain ;
            adoquery.SQL.Add( 'insert into test_unicode ( TEINT_ID , TEINT_DES_FR, TEINT_DES_RU ) values ( :sID , :sTEINT_FR,  :sTeint_RU )' );
     
            adoquery.Parameters.Clear ;
     
            psValue := '5' ;
            adoquery.Parameters.CreateParameter(  'sID', ftInteger, pdInput, 0 , psValue ) ;
     
            psValue := 'bleu' ;
            iLen := Length(psValue) ;
            adoquery.Parameters.CreateParameter(  'sTeint_FR', ftString, pdInput, iLen , psValue ) ;
     
            psValue := XXXXX ;
            iLen := Length(psValue) ;
            adoquery.Parameters.CreateParameter(  'sTeint_RU', ftString, pdInput, iLen , psValue ) ;
     
            adoquery.ExecSQL ;
     
            ShowMessage( 'Ok' );
     
        except
          on e : Exception do
            ShowMessage( e.Message );
        end;
      finally
        adoquery.Free ;
      end;
     
     
    end;
    note : remplace les XXXXX par 'белый'

  3. #3
    Futur Membre du Club
    Inscrit en
    Juillet 2002
    Messages
    8
    Détails du profil
    Informations forums :
    Inscription : Juillet 2002
    Messages : 8
    Points : 8
    Points
    8
    Par défaut
    Bonjour,
    Merci pour votre réponse. Cela me permet d'arriver au même niveau que vous.

    Effectivement, l'option permet d'arriver à faire les insert et les update. Les select en revanche ne fonctionnent pas

    Et quand je lis cela, cela me fait peur...
    OraOLEDB does not support parameters of N datatypes in the WHERE clause of SQL statements

    http://docs.oracle.com/cd/B10501_01/...5498/using.htm

  4. #4
    Membre habitué
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2012
    Messages
    92
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2012
    Messages : 92
    Points : 159
    Points
    159
    Par défaut
    les selects ont fonctionné de suite par contre je n'ai pas essayé dans un filtre de recherche

    au niveau de la version du client, j'ai essayé la 10.2.0 et la 11.2.0

    Paramètre de la base de données :
    SELECT * FROM V$NLS_PARAMETERS
    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
    NLS_LANGUAGE = FRENCH
    NLS_TERRITORY = FRANCE
    NLS_CURRENCY = €
    NLS_ISO_CURRENCY = FRANCE
    NLS_NUMERIC_CHARACTERS = , 
    NLS_CALENDAR = GREGORIAN
    NLS_DATE_FORMAT = DD/MM/RR
    NLS_DATE_LANGUAGE = FRENCH
    NLS_CHARACTERSET = WE8ISO8859P15
    NLS_SORT = FRENCH
    NLS_TIME_FORMAT = HH24:MI:SSXFF
    NLS_TIMESTAMP_FORMAT = DD/MM/RR HH24:MI:SSXFF
    NLS_TIME_TZ_FORMAT = HH24:MI:SSXFF TZR
    NLS_TIMESTAMP_TZ_FORMAT = DD/MM/RR HH24:MI:SSXFF TZR
    NLS_DUAL_CURRENCY = €
    NLS_NCHAR_CHARACTERSET = AL16UTF16
    NLS_COMP = BINARY
    NLS_LENGTH_SEMANTICS = BYTE
    NLS_NCHAR_CONV_EXCP = FALSE
    SELECT * FROM NLS_SESSION_PARAMETERS
    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
    NLS_LANGUAGE = FRENCH
    NLS_TERRITORY = FRANCE
    NLS_CURRENCY = €
    NLS_ISO_CURRENCY = FRANCE
    NLS_NUMERIC_CHARACTERS = , 
    NLS_CALENDAR = GREGORIAN
    NLS_DATE_FORMAT = DD/MM/RR
    NLS_DATE_LANGUAGE = FRENCH
    NLS_SORT = FRENCH
    NLS_TIME_FORMAT = HH24:MI:SSXFF
    NLS_TIMESTAMP_FORMAT = DD/MM/RR HH24:MI:SSXFF
    NLS_TIME_TZ_FORMAT = HH24:MI:SSXFF TZR
    NLS_TIMESTAMP_TZ_FORMAT = DD/MM/RR HH24:MI:SSXFF TZR
    NLS_DUAL_CURRENCY = €
    NLS_COMP = BINARY
    NLS_LENGTH_SEMANTICS = BYTE
    NLS_NCHAR_CONV_EXCP = FALSE

    EDIT :
    1ére méthode pour le select : OK

    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
    procedure TfrmMain.Button3Click(Sender: TObject);
    var
      adoquery : TADOQuery ;
    begin
     
      adoquery := TADOQuery.Create(nil);
      try
        try
            adoquery.Connection := dmdConnect.cntMain ;
            adoquery.SQL.Add( 'select * from test_unicode where TEINT_DES_RU like N''XXXXX'' ' );
     
            adoquery.Open ;
     
            if not adoquery.Eof then
              ShowMessage( 'Ok : ' + adoquery.FieldByName ( 'TEINT_DES_RU' ).AsString )
            else
              ShowMessage( 'NOk');
     
        except
          on e : Exception do
            ShowMessage( e.Message );
        end;
      finally
        adoquery.Free ;
      end;
     
    end;
    XXXXX = %елы%

    2éme méthode : avec les paramètres : pas encore OK

  5. #5
    Futur Membre du Club
    Inscrit en
    Juillet 2002
    Messages
    8
    Détails du profil
    Informations forums :
    Inscription : Juillet 2002
    Messages : 8
    Points : 8
    Points
    8
    Par défaut
    J'ai refait les tests avec les select.
    Que ce soit avec le préfixe N ou les paramètres, cela ne fonctionne pas...
    On a les mêmes paramètres de session. Le champ de mon coté est typé en nvarchar2. Est-ce aussi le cas de votre coté ?

    La solution du filtre de recherche fonctionne mais pose le problème des performances . Je préférerai donc éviter.

  6. #6
    Membre habitué
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2012
    Messages
    92
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2012
    Messages : 92
    Points : 159
    Points
    159
    Par défaut
    voici le script de la table. le champs est bien du NVARCHAR2

    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
    DROP TABLE TEST_UNICODE CASCADE CONSTRAINTS;
     
    CREATE TABLE TEST_UNICODE
    (
      TEINT_ID      INTEGER,
      TEINT_DES_FR  VARCHAR2(50 BYTE),
      TEINT_DES_RU  NVARCHAR2(50)
    )
    TABLESPACE HADHOC_TAB
    RESULT_CACHE (MODE DEFAULT)
    PCTUSED    0
    PCTFREE    10
    INITRANS   1
    MAXTRANS   255
    STORAGE    (
                INITIAL          64K
                NEXT             1M
                MINEXTENTS       1
                MAXEXTENTS       UNLIMITED
                PCTINCREASE      0
                BUFFER_POOL      DEFAULT
                FLASH_CACHE      DEFAULT
                CELL_FLASH_CACHE DEFAULT
               )
    LOGGING 
    NOCOMPRESS 
    NOCACHE
    NOPARALLEL
    MONITORING;

  7. #7
    Futur Membre du Club
    Inscrit en
    Juillet 2002
    Messages
    8
    Détails du profil
    Informations forums :
    Inscription : Juillet 2002
    Messages : 8
    Points : 8
    Points
    8
    Par défaut
    Bonjour,
    Désolé pour le temps de réponse mais j'ai eu d'autres dossiers qui sont venus entre temps.
    J'ai réussi à trouver des astuces pour m'en sortir.
    Pour les select, je me suis finalement résolu à passer par les filtres de recherche. Je limite la casse en mettant dans la clause where le nombre de caractères.
    Pour les updates, la valeurs étant disponible dans d'autres table, je passe par des requetes update/select. C'est loin d'être optimal mais au moins çà marche.
    Merci encore pour votre aide.

  8. #8
    Membre habitué
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2012
    Messages
    92
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2012
    Messages : 92
    Points : 159
    Points
    159
    Par défaut
    as tu un exemple pour ton select ?

    étant en plein tests, j'ai rencontré 2 problèmes. les requêtes insert - select et update -select ne fonnctionnent plus depuis que j'ai rajouté l'option NDataType=TRUE dans la chaîne de connexion avec OraOleDB.
    exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    update ma_table set ( ma_table.date1 , ma_table.date2 , ma_table.int1 ) = ( select sysdate, sysdate , 0 from dual ) where ma_table.id = :id
    j'a un e erreur ORA-00936: expression absente

    la seule solution que j'ai trouvé, c'est de mettre la requête entre begin et end
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    begin
    update ma_table set ( ma_table.date1 , ma_table.date2 , ma_table.int1 ) = ( select sysdate, sysdate , 0 from dual ) where ma_table.id = :id;
    end;

  9. #9
    Futur Membre du Club
    Inscrit en
    Juillet 2002
    Messages
    8
    Détails du profil
    Informations forums :
    Inscription : Juillet 2002
    Messages : 8
    Points : 8
    Points
    8
    Par défaut
    Bonjour,
    Pour le select, je passe par les filtres et je limite la casse en mettant la taille dans la clause where (perf).
    Cela donne un code comme celui ci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
      Adoquery1.SQL.Text := 'select ID_SERVICE, LIBELLE, ID_SOCIETE from service where length(LIBELLE) = :pLibelle and (ID_SOCIETE = :pIdSociete or ID_SOCIETE =0)' ; 
      Adoquery1.Parameters.ParamByName('pLibelle').value := 4;
      Adoquery1.Parameters.ParamByName('pIdSociete').value := 4059;
      Adoquery1.Filter := 'LIBELLE = ''商務旅遊'' ';
      Adoquery1.Filtered := true;
      Adoquery1.Open;
    Pour les update et insert, si la valeur est déjà dans la BD, je passe par une requête du type :
    UPDATE TEST_UNICODE3 T3
    SET TEINT_DES_RU = (select TEST_UNICODE2.TEINT_DES_RU from TEST_UNICODE2 where T3.TEINT_ID = TEST_UNICODE2.TEINT_ID)
    Cela suppose bien entendu que l'on sache où est la valeur dans la base de données (à combiner parfois avec le select filtré).


    Ensuite, là, je suis en train de mettre en place un troisième montage que je vais tenter d'utiliser le moins possible.
    J'ai deux AdoConnection d'ouvert AdoConnection1 est la connection normale et AdoConnection2 qui a l'option NDataType à true. J'insère des données via cette dernière connection dans une table temporaire et je met à jour ensuite via un update. Je suis obligé de passer par un montage aussi compliqué car l'option NDataType génère dans mon appli des erreurs incompréhensibles. Je préfère donc utiliser cette options avec parcimonie.


    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
     
      AdoConnection1.BeginTrans;
      QrInsDonnees.SQL.text := ' insert into TEST_UNICODE2 (TEINT_ID, TEINT_DES_FR, TEINT_DES_RU) ' +
                                ' values (:pId, :pfr, :pru) ';
     
      QrInsDonnees.Parameters.ParamByName('pId').Value :=  6;
      QrInsDonnees.Parameters.ParamByName('pfr').Value :=  'Gaz naturel';
      QrInsDonnees.Parameters.ParamByName('pru').Value :=  'природный газ';
      QrInsDonnees.ExecSQL;
     
      qrMajDonnees.SQL.Text := 'insert into TEST_UNICODE3 T3 (TEINT_ID, TEINT_DES_FR, TEINT_DES_RU) ' +
                               'select TEINT_ID, TEINT_DES_FR, TEINT_DES_RU from TEST_UNICODE2 where TEINT_ID = 6 ';
     
      qrMajDonnees.ExecSQL;
      AdoConnection1.CommitTrans;

  10. #10
    Futur Membre du Club
    Inscrit en
    Juillet 2002
    Messages
    8
    Détails du profil
    Informations forums :
    Inscription : Juillet 2002
    Messages : 8
    Points : 8
    Points
    8
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
      Adoquery4.SQL.Text := 'UPDATE TEST_UNICODE3 T3 ' +
                            ' SET TEINT_DES_RU = (select TEST_UNICODE2.TEINT_DES_RU from TEST_UNICODE2 where T3.TEINT_ID = TEST_UNICODE2.TEINT_ID) where T3.TEINT_ID = :pId';
      Adoquery4.Parameters.ParamByName('pId').Value := 5;
     
      Adoquery4.ExecSQL;
      Adoquery4.Close;

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

Discussions similaires

  1. Delphi Oracle et unicode
    Par jeffray03 dans le forum Bases de données
    Réponses: 10
    Dernier message: 08/07/2009, 16h53
  2. Réponses: 1
    Dernier message: 07/11/2006, 15h52
  3. Importer données Unicode Oracle dans SQL-Server 2000.
    Par LaFraise dans le forum MS SQL Server
    Réponses: 3
    Dernier message: 12/12/2005, 14h54
  4. [Kylix] sqlconnection + oracle
    Par tibo55555 dans le forum EDI
    Réponses: 1
    Dernier message: 02/09/2002, 09h09
  5. Problème d'installation oracle 8.1.7 sous NT
    Par Anonymous dans le forum Installation
    Réponses: 7
    Dernier message: 02/08/2002, 14h18

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