[NEWSboard IBMi Forum]

Hybrid View

  1. #1
    Registriert seit
    Feb 2009
    Beiträge
    12

    emb. SQL und UTF-16

    Hallo zusammen,

    Nach Umstellung eines Feldes auf UTF-16 CCSID(1200) habe ich folgendes Problem:
    Ich bekomme mittels generierter SqlAnweisung nicht mehr das gewünschte Ergebnis. Sondern es werden alle Datensätze aus der Datei selektiert.

    Anbei hänge ich mal den Codeauschnitt.

    Code:
    H CCSID(*UCS2 : 1200)     
    :
    D SqlStatement    s           5000C   VARYING        
    D US1             s             80C   VARYING
    D Search1         s             80C   VARYING     
    D §HK             s              1    inz(X'7D')                           Hochkomma definieren             
    :
    C/exec sql                                  
    C+ declare C1 scroll Cursor for S1          
    C/end-exec                                  
    :
    C                   EVAL      US1 =%UCS2(' where upper(tititl)') +      
    C                                 %UCS2(' = ') +                       
    C                                 %UCS2(§HK) + %trim(search1) +         
    C                                 %UCS2(§HK)
    :
    Im Debug erhalte ich folgenden Inhalt US1 =  where upper(tititl) = 'TOP'  
    :
     /free                                                       
         SqlStatement                                            
          =  %UCS2('select * from ')                             
          +  %UCS2(' ') + %UCS2(%trim(§file)) + %UCS2(' ')       
          +  %ucs2(' ') + %trim(Us1) + %ucs2(' ');               
     /end-free                                                   
    :
    Im Debug: SQLSTATEMENT = select * from  MDPROP03  where upper(tititl) = 'TOP'   
    :
    C/exec sql                          
    C+ prepare S1 from :SqlStatement    
    C/end-exec
    :
    C/exec sql               
    C+ open C1               
    C/end-exec
    :
    C/exec sql                                             
    C+ FETCH RELATIVE :rows FROM C1 INTO :ds_MDPROP03      
    C/end-exec
    : 
    :
    C/exec sql            
    C+ close C1           
    C/end-exec
    In der Datei ist das Feld TITITL wie folgt definiert:
    TITITL     GRAPHIC        60     120       290
    ID des codierten Zeichensatzes . . . . . :    1200          
    UCS2- oder Unicode-Konvertierung  . . . . :  *CONVERT
    Wäre toll wenn jemand eine Lösung dieses Problemes parat hat.

  2. #2
    Registriert seit
    Feb 2009
    Beiträge
    12

    Ergänzung

    Hallo zusammen, ein kleiner Nachtrag.

    Hat jemand vielleicht ein Beispiel, für ein SQLRPGLE Programm. Welches Felder die mit CCSID 1200 definiert sind, aus einer Datei liest?

    Das "normale" Lesen der Daten mit setll, chain, reade usw mit einem UTF-16 Schlüsselfeld geht ohne Probleme. Nur die Verwendung generischer SQL-Abfragen z.B. für Volltextsuche macht Probleme.

    Wäre nett wenn mir jemand weiterhelfen könnt.

    Danke
    Thorsten

  3. #3
    Registriert seit
    Feb 2001
    Beiträge
    20.696
    Also ALLE Datensätze kann ich mir fast nicht vorstellen. Da muss der Select irgendwo falsch sein.

    Probiere das erst mal mit STRSQL aus.
    Ggf. musst du die Felder erst wieder in UCS2 casten:

    where upper(cast(feld as graphic(nn) ccsid 13488)) = 'TOP'

    Allerdings ist hier das Problem, dass die Konstante 'TOP' nicht UCS2 ist !
    Also ist die ggf. auch zu casten.

    Das Hauptproblem ist, das der UCS2-SQL-String erst in Job-CCSID konvertiert wird und nicht so als UCS2 verwendet wird.
    UCS2-Felder funktionieren nur als Hostvariablen (CLI-Interface) und leider nicht bei dynamischem SQL.

    Du kannst dir das mit der %UCS2 für das Statement schenken.
    Dienstleistungen? Die gibt es hier: http://www.fuerchau.de
    Das Excel-AddIn: https://www.ftsolutions.de/index.php/downloads
    BI? Da war doch noch was: http://www.ftsolutions.de

  4. #4
    Registriert seit
    Feb 2009
    Beiträge
    12
    Versuche ich unter STRSQL alle mögliche Formen des Cast's wie z.B.:
    select * from MDPROP03
    where cast(TITITL as graphic(60) ccsid 13488)
    = cast('Top' as graphic(60) ccsid 13488)

    Erhalte ich immer die Fehlermeldung:
    Zeichenumsetzung zwischen CCSID 65535 und CCSID 13488 ungültig.

    Folgendes funktioniert unter STRSQL:
    select * from MDPROP03 where cast(TITITL as char(20)) = 'Top'
    select * from MDPROP03 where UPPER(cast(TITITL as char(60))) = cast('TOP' as char(60))
    wäre aber unsinnig da ich eben auch Unicode Zeichen bekomme,die beim Cast auf CHAR "verschluckt" werden.

    Führe ich das ganze im Programm aus: Zeigt mir der Debugger
    SQLStatement =
    select * from MDPROP03 where UPPER(cast(TITITL as char(60))) = cast('TOP' as char(60))

    und ich bekomme folgende Fehlermeldung beim Prepare Cursor
    SQLCODE: -104, SQLSTATE: 42601, SQLERRMC: AS
    andere Abfragen die ich mit der gleichen Routine zusammenbaue funktionieren korrekt, wenn ich eben kein Graphic Feld abzufragen versuche.

    Ich versteh die Welt nicht mehr...

  5. #5
    Registriert seit
    Feb 2001
    Beiträge
    20.696
    Wichtig ist, dass dein Job nicht mit CCSID 65535 läuft !!!
    Wie soll SQL da korrekt umsetzen können ?
    Dienstleistungen? Die gibt es hier: http://www.fuerchau.de
    Das Excel-AddIn: https://www.ftsolutions.de/index.php/downloads
    BI? Da war doch noch was: http://www.ftsolutions.de

  6. #6
    Registriert seit
    Feb 2009
    Beiträge
    12
    Okay das ist klar, habe ich im Eifer des Gefechtes schlichtweg übersehen.

    Der Job unter dem das Ganze passiert läuft unter der CCSID 1141.

    Die CCSID des Feldes ist 1200.

    zum SQL-104: wenn ich das SQL aus dem Feld Sql-Statement direkt im SQL eingebe bekomme ich keinen Fehler.

    zum %UCS2 bzw. die Arie
    Das Feld TITITL hat die CCSID 1200, baue ich mir den SQlStatement String ohne %UCS2 zusammen bekomme ich die Meldung *RNF7421 30 1 Operanden sind mit der Art des Operators nicht kompatibel. Deswegen die %UCS Arie.
    Wenn jemand einen anderen Weg kennt bin ich dankbar.

    Das mit allen Sätzen könnte ein Folgefehler nach dem FetchCsr sein.

  7. #7
    Registriert seit
    Feb 2009
    Beiträge
    12
    Ich denke ich habe die Ursache des Problems gefunden:

    Und zwar in der Definition des SQLStatements.
    Dieses war als SqlStatement s 5000C VARYING definiert nach dem ich es auf 5000 Alpha angepasst habe, bekomme ich nun das gewünschte Ergebnis.

  8. #8
    Registriert seit
    Feb 2009
    Beiträge
    12
    Nun noch eine Frage, zum LIKE, CAST und CCSID 1200.

    Wenn mein SQL "....where UPPER(cast(TITITL as graphic(60) ccsid 1200)) like cast('%TOP%' as graphic(60) ccsid 1200) " lautet, bekomme ich nur den Titel der genau TOP heißt. Andere Titel in der Tabelle die z.B. "stops" enthalten werden nicht angezeigt.
    Meine Vermutung läuft dahin dass das '%' nicht in im Cast sein darf.
    Aber wie lautet der String dann? Mit
    Code:
    select * from  MDPROP03                                    
    where upper(cast(TITITL as graphic(60) ccsid 1200))        
    like ('%'||cast('TOP'  as graphic(60) ccsid 1200)||'%')    
    SELECT * FROM MDPROP03 
    WHERE upper(cast(TITITL as graphic(60) ccsid 1200)) 
    like '%' CONCAT cast('TOP' as graphic(60) ccsid 1200) 
    CONCAT '%'
    bekomme ich das gleiche Ergebnis.

  9. #9
    Registriert seit
    Mar 2002
    Beiträge
    5.365
    select ... where ... like ?
    preparen und anchließend open ... using :myHostVar
    sollte da eigentlich funzen, dann fällt die UCS Casterei wieder weg und myHostVar muss dann ein graphic Feld sein.

    D*B

    Zitat Zitat von tsh1970 Beitrag anzeigen
    Nun noch eine Frage, zum LIKE, CAST und CCSID 1200.

    Wenn mein SQL "....where UPPER(cast(TITITL as graphic(60) ccsid 1200)) like cast('%TOP%' as graphic(60) ccsid 1200) " lautet, bekomme ich nur den Titel der genau TOP heißt. Andere Titel in der Tabelle die z.B. "stops" enthalten werden nicht angezeigt.
    Meine Vermutung läuft dahin dass das '%' nicht in im Cast sein darf.
    Aber wie lautet der String dann? Mit
    Code:
    select * from  MDPROP03                                    
    where upper(cast(TITITL as graphic(60) ccsid 1200))        
    like ('%'||cast('TOP'  as graphic(60) ccsid 1200)||'%')    
    SELECT * FROM MDPROP03 
    WHERE upper(cast(TITITL as graphic(60) ccsid 1200)) 
    like '%' CONCAT cast('TOP' as graphic(60) ccsid 1200) 
    CONCAT '%'
    bekomme ich das gleiche Ergebnis.
    AS400 Freeware
    http://www.bender-dv.de
    Mit embedded SQL in RPG auf Datenbanken von ADABAS bis XBASE zugreifen
    http://sourceforge.net/projects/appserver4rpg/

  10. #10
    Registriert seit
    Feb 2001
    Beiträge
    20.696
    Das Problem beim casten ist die fixe Länge an stelle von VARGRAPHIC bzw. VARCHAR.
    Dadurch wird rechstbündig mit Leerzeichen aufgefüllt, die natürlich zum Suchmuster dazugehören.

    AUch bei Hostvariablen ist ggf. die Definition varying erforderlich oder im SQL ein trim(: MyHstVar) !
    Dienstleistungen? Die gibt es hier: http://www.fuerchau.de
    Das Excel-AddIn: https://www.ftsolutions.de/index.php/downloads
    BI? Da war doch noch was: http://www.ftsolutions.de

  11. #11
    Registriert seit
    Mar 2002
    Beiträge
    5.365
    ad CCSID65535:
    das bezieht sich auf den Cast des Literals (das hat keine CCSID)
    das geht über einen doppelten CAST
    CAST(CAST('TOP' as char(60) ccsid 273) as graphic(60) CCSID 13488)

    ad Unicode:
    ja was denn nun, 1200 oder 13488

    ad SQL-104:
    ungültiger Token => dein Statement ist falsch!

    ad %UCS :
    cast des SQL Strings ist unnötiger Schnickschnack

    ad Cast Arie insgesamt:
    wenn das Dateifeld verträglich zu dem Programmfeld deklariert ist, braucht es da keine Konvertierungen.

    ad alle Sätze:
    schu dir mal deinen SQLCODE nach jedem Statement an, was da wirklich krumm geht

    D*B

    Zitat Zitat von tsh1970 Beitrag anzeigen
    Versuche ich unter STRSQL alle mögliche Formen des Cast's wie z.B.:
    select * from MDPROP03
    where cast(TITITL as graphic(60) ccsid 13488)
    = cast('Top' as graphic(60) ccsid 13488)

    Erhalte ich immer die Fehlermeldung:
    Zeichenumsetzung zwischen CCSID 65535 und CCSID 13488 ungültig.

    Folgendes funktioniert unter STRSQL:
    select * from MDPROP03 where cast(TITITL as char(20)) = 'Top'
    select * from MDPROP03 where UPPER(cast(TITITL as char(60))) = cast('TOP' as char(60))
    wäre aber unsinnig da ich eben auch Unicode Zeichen bekomme,die beim Cast auf CHAR "verschluckt" werden.

    Führe ich das ganze im Programm aus: Zeigt mir der Debugger
    SQLStatement =
    select * from MDPROP03 where UPPER(cast(TITITL as char(60))) = cast('TOP' as char(60))

    und ich bekomme folgende Fehlermeldung beim Prepare Cursor
    SQLCODE: -104, SQLSTATE: 42601, SQLERRMC: AS
    andere Abfragen die ich mit der gleichen Routine zusammenbaue funktionieren korrekt, wenn ich eben kein Graphic Feld abzufragen versuche.

    Ich versteh die Welt nicht mehr...
    AS400 Freeware
    http://www.bender-dv.de
    Mit embedded SQL in RPG auf Datenbanken von ADABAS bis XBASE zugreifen
    http://sourceforge.net/projects/appserver4rpg/

Similar Threads

  1. RPGLE - SQL
    By christian_lettner in forum NEWSboard Programmierung
    Antworten: 2
    Letzter Beitrag: 16-11-06, 10:15
  2. SQL - Cursor vernichten ?!?
    By FNeurieser in forum NEWSboard Programmierung
    Antworten: 3
    Letzter Beitrag: 11-10-06, 14:53
  3. SQL und OBJLCK
    By malzusrex in forum IBM i Hauptforum
    Antworten: 8
    Letzter Beitrag: 19-09-06, 11:04
  4. SQL - Fehler
    By Kaufmann in forum IBM i Hauptforum
    Antworten: 11
    Letzter Beitrag: 28-06-06, 14:11
  5. SQL .. for update of (RPG embedded SQL)
    By loeweadolf in forum NEWSboard Programmierung
    Antworten: 2
    Letzter Beitrag: 01-06-06, 09:43

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • You may not post attachments
  • You may not edit your posts
  •