Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   TSQLConnection / Oracle / NSL_CHARACTERSET ändern (https://www.delphipraxis.net/171994-tsqlconnection-oracle-nsl_characterset-aendern.html)

tofse 6. Dez 2012 11:29

Datenbank: Oracle • Version: 10.2 • Zugriff über: TSQLConnection

TSQLConnection / Oracle / NSL_CHARACTERSET ändern
 
Hallo,
ich greife auf die Oracle Datenbank einer anderen Software zu. Dort sind Passwörter "verschlüsselt" hinterlegt.
Das wird gemacht, um den Benutzerstamm dieser Software als Basis für Eigenentwicklungen zu verwenden.
Der Algorithmus zum Verschlüsseln ist bekannt.

Nun das Problem: Wenn ich das Passwort per SQL auslese, kommt der verschlüsselt String zurück, funktioniert prima, außer das unverschlüsselte Zeichen ist ein Sonderzeichen.
In der Datenbank steht z.B. ÝÒåçÙç, SQL liefert aber ÝÒåçÙç (an der letzten Stelle steht hier im Beispiel ein !)
Zunächst dachte ich, der Algorithmus hat einen Fehler, der sich bei den Sonderzeichen zeigt.
Das konnte ich aber widerlegen, denn es wird auch mit einem PHP Skript auf die Datenbank zugegriffen. Zunächst hatte ich das gleiche Phänomen, aber man kann in der Connection
Code:
oci_connect('user','pw','......','WE8MSWIN1252')
character_set angeben. Mit der richtigen Angabe für diese Datenbank hat es dann auch funktioniert. Also muss es daran liegen.

So, nun zur eigentlichen Frage :-D
Wie kann ich NLS_CHARACTERSET in Delphi (TSQLConnection) setzen???? Ich denke, damit wird es dann funktionieren.

Grüße
Christof

p80286 6. Dez 2012 11:35

AW: TSQLConnection / Oracle / NSL_CHARACTERSET ändern
 
Vielleicht hilft Dir dies weiter?

Gruß
K-H

tofse 6. Dez 2012 11:38

AW: TSQLConnection / Oracle / NSL_CHARACTERSET ändern
 
Leider nicht, da wird ja nicht gezeigt, wie es unter Delphi anzugeben ist.
Ich denke...hoffe...dass man es einfach in der Connection (ähnlich wie bei PHP) einfach mit angeben kann.

Ich hatte es schon mit ALTER SESSION versucht, aber da kam irgendwas mit nicht zulässig...

EgonHugeist 6. Dez 2012 13:28

AW: TSQLConnection / Oracle / NSL_CHARACTERSET ändern
 
AFAIK funktioniert mit Oracle nicht so ohne weiteres.

Bei Oracle und FireBird muß man den Client-Characterset vor dem Connect wissen, da du erst alle Envirnonment-Variablen hinterlegen mußt.

function OCIEnvNlsCreate(var envhpp: POCIEnv; mode: ub4; ctxp: Pointer;
malocfp: Pointer; ralocfp: Pointer; mfreefp: Pointer; xtramemsz: size_T;
usrmempp: PPointer; charset, ncharset: ub2): sword; cdecl;

wäre hier die Lösung. Hast du Zugriff zum Code der Komponente?

CharSet WE8MSWIN1252 hat die ID 178.

Ich weiß, Zeos unterstützt das. Du könntest mit Zeos einen Export machen und dann danach alles im wieder importieren, da es sich hierbei einfach um ein Encodierungs-Problem zu handeln scheint..

Gruß Michael

tofse 6. Dez 2012 13:36

AW: TSQLConnection / Oracle / NSL_CHARACTERSET ändern
 
oje, ich dachte das wäre so einfach wie in php :(
In SQL bin ich fit, aber das Ganze drum herum und DB Administration, da hab ich null Plan...

Dein Lösungsansatz wäre mir da zu hoch...

shmia 6. Dez 2012 13:59

AW: TSQLConnection / Oracle / NSL_CHARACTERSET ändern
 
Wenn man verschlüsselte Passwörter in einer Datenbank, XML- oder Inifile speichert
sollte man unbedingt die binären Daten hexadezimal (Base16) oder Base64 kodieren,
damit man grundsätzlich den Problemen mit dem Zeichensatz aus dem Weg geht :!:

tofse 6. Dez 2012 14:07

AW: TSQLConnection / Oracle / NSL_CHARACTERSET ändern
 
Danke für den Hinweis, aber das steht nicht zur Diskussion, da es sich um einen großen Softwareanbieter handelt, und wir darauf keinen Einfluss haben. Sind schon froh, dass wir den Algorithmus haben.

jobo 6. Dez 2012 15:48

AW: TSQLConnection / Oracle / NSL_CHARACTERSET ändern
 
Du musst glaub ich "nur" NLS_LANG im OS Environment passend setzen, bevor(!) du connectest.

p80286 6. Dez 2012 16:15

AW: TSQLConnection / Oracle / NSL_CHARACTERSET ändern
 
ok ich arbeite mit ADO aber verschlüsselte Passwörter habe ich auch schon ausgelesen. ggf ist die fehlerhafte Darstellung nur ein Darstellungsproblem?
Hast Du mal einen Hex-Dump Deiner Passwörter erstellt?

Gruß
K-H

EgonHugeist 6. Dez 2012 21:33

AW: TSQLConnection / Oracle / NSL_CHARACTERSET ändern
 
Zitat:

Zitat von tofse (Beitrag 1194551)
oje, ich dachte das wäre so einfach wie in php :(

Ist es eigentlich auch, nur eben nicht mit der UnicodeIDE.

So, wie ich das sehe, brauchst du eine Komponente, mit welcher du den CharacterSet selber bestimmst und bei Bedarf sogar auf den nativen nicht-zu-UnicodeString(stimmt die XE-Compiler Angabe?), um dein Problem zu lösen.

Erst einmal würd ich sagen Finger weg von Ideen wie zu Laufzeit den CharacterSet ändern, wenn du eine UnicodeIDE benutzt:

Ich gehe mal davon aus, das die meisten Komponenten da gleich funktionieren: Stelle den vom Benutzer gewüschten CharacterSet ein, dann macht der Server(außer MsSQL) alle notwendigen Encodierungen und die DB-Zugriffs Komponente weiß, wie sie den vom Server erhaltenen Ansi-String(CP-WhatEver) zum UnicodeString mappt. Sollter der User den CharSet nicht angegeben haben, frage die DB danach und stelle die AnsiToUnicode und umgekehrt Functionen darauf ein, da ein Casten nur zufällig passende Resultate geliefert, wenn ServerCP <> DefaultCodePage. (auch ADO bleibt davon nicht verschont, tut es jedoch intern) Blablabla..

Wenn du den CharSet zur Laufzeit änderst, passt vielleicht der String, den du dir wünschst, jedoch ist es möglich, daß alle anderen Encodierungen totalen Stuß fabrizieren. (da die Componente noch immer den AnsiString mit CP-WhatEver erwartet)

Daher versuchs mal mit dem Vorschlag von jobo.:thumb:

Wenn dann alles nix hilft:

Lade Zeos7-Beta herunter und installiere die Komponente.
Benutze die TZConnection anstadt oder zusätzlich zu der TSQLConnection (kenne ich nicht :oops:)

TZConnection.ClientCodePage := 'WE8MSWIN1252';
TZConnection.UserName etc.....

Verbinde dich mit der DB.
Delphi-Quellcode:
var
  ResultSet: IZResultSet;
  rs: RawByteString;
begin
  with ZConnection1.DbcConnection.PrepareStatement('select CryptedField from deine.tabelle') do
  begin
    ResultSet := ExecuteQueryPrepared;
    while ResultSet.Next do
      rs := ResultSet.GetBinaryStringByName('CryptedField'); //Ergebis ist der direkt von der DB gelieferten nicht encodierte String
    ResultSet.Close;
    ResultSet := nil;
    Close;
  end;
end;
Das funzt auf jeden Fall.
Kannst du damit etwas anfangen? Zeos läßt dem Benutzer in jeder hinsicht alle Freiheiten.

Gruß Michael

tofse 7. Dez 2012 08:08

AW: TSQLConnection / Oracle / NSL_CHARACTERSET ändern
 
ich schaue mir das mal an.
Irgendwie hatte ich es mir so vorgestellt
Zitat:

TZConnection.ClientCodePage := 'WE8MSWIN1252';
TZConnection.UserName etc.....
Danke

Delbor 8. Dez 2012 08:33

AW: TSQLConnection / Oracle / NSL_CHARACTERSET ändern
 
Hi tofse

Du arbeitest mit TSQLConnection, also mit DBExpress? Seit mW. D2010 gibt es dazu ein komplett überarbeitetes DBX-Framework. Und dieses enthält Routinen, um empfangene Strings in den Zeichensatz der Anwendung umzuwandeln.

Ich selbst arbeite zwar mit MySQL, greife aber auch mit den DBExpress-Komponenten auf den Server zu. Ein Stringgrid befülle ich zB. wie folgt:

Delphi-Quellcode:
    while not DelborDataMod.SQLDataSetXE.Eof do
    begin
      StrGridKathegory.Cells[0, i] := IntToStr(DelborDataMod.SQLDataSetXE.FieldByName('Kath_ID').AsInteger);
      StrGridKathegory.Cells[1, i] := UTF8ToUnicodeString(DelborDataMod.SQLDataSetXE.FieldByName('Kategorie').AsString);
      DelborDataMod.SQLDataSetXE.Next;
      inc(i);
    end;
Damit hast du zwar nicht den Zeichensatz des Servers geändert, sondern nur den der Anwendung. Ausserdem müsstest du dir noch was einfallen lassen, falls du mit Datensensitiven Komponenten arbeitest - ohne dein Zutun zeigen die sonst den Zeichensatz so an, wie er vom Server kommt.
Natürlich hat der Server auch eine sessionspezifische Variable CLIENTDATASET - eine Oracel-DB wohl ebenso wie MySQL.

Gruss
Delbor

PS:

Zitat:

Wie kann ich NLS_CHARACTERSET in Delphi (TSQLConnection) setzen????
Hmm... Solange das der Charakterset deiner Verbindung ist, kannst du das sicher tun - in MySQL gibt's für sowas das SQL-Statement 'SET @@session.character_set_client = ''wasauchimmer'''.
Oracel müsste wohl auch sowas haben.


Alle Zeitangaben in WEZ +1. Es ist jetzt 05:36 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz