2016-06-23 23 views
0

Ich habe eine VB6-App, die eine Oracle (12) PL/SQL-gespeicherte Prozedur aufruft. Es verwendet ein ADODB-Verbindungsobjekt.Wie verhindern, dass die Parameter von VB6 zu Oracle mit ADO getrimmt werden

String-Parameter, die von der App übergeben werden, können nachstehende Leerzeichen enthalten. Wenn Oracle sie empfängt, sind alle nachgestellten Leerzeichen verschwunden.

Ich möchte die nachgestellten Leerzeichen bleiben. Ich habe überall gesucht und kann keine Referenz online auf Verhalten von VB, ADO oder Oracle finden, die besagt, dass nachfolgende Leerzeichen in Parameter getrimmt werden sollen.

In Oracle sind die Parameter der gespeicherten Prozedur als varchar2 definiert. In VB6 verwende ich CreateParameter(), um die Parameter als adVarChar hinzuzufügen (ich habe andere String-Typen ausprobiert und es hilft nicht). Der Anruf gibt den Namen, Typ, Richtung, Größe und Wert an.

Kurz vor dem Aufruf von Execute kann ich die Command.Parameters-Auflistung überprüfen und überprüfen, dass alle nachfolgenden Leerzeichen vorhanden sind.

Oracle-Referenzen geben explizit an, dass mit dem varchar2-Datentyp die folgenden Leerzeichen nicht ignoriert werden.

Kann jemand beschreiben, ob es eine Option in VB oder der Datenbank gibt, die dies verursacht, und kann ausgeschaltet werden?

+0

Können Sie bitte Ihren Code zeigen? –

+0

IIRC, die abschließenden Leerzeichen werden im DB gespeichert und sind dort, wenn Sie den Wert abrufen. Es sind _comparons_, wo sie ignoriert werden, dh der SQL-Sprachstandard besagt, dass 'Foo' gleich 'Foo' ist, wenn WHERE-Klausel und CASE-Typ überprüft werden. –

+0

Ah, hier ist eine Dokumentation zu diesem Thema. Es stammt von Sql Server und nicht von Oracle, aber es bezieht sich wiederum auf den ansi-Standard, dem wahrscheinlich auch Oracle folgt (Ansi SQL-92, Abschnitt 8.2, , Allgemeine Regeln # 3) https://support.microsoft .com/de-de/kb/316626 In Sql Server können Sie dies umgehen, indem Sie anstelle eines Gleichheitsvergleichs einen LIKE-Vergleich durchführen. Keine Ahnung, ob Oracle das gleiche Verhalten hat. –

Antwort

0

Funktioniert es, wenn Sie eine Null anhängen, dh. chr(0) bis zum Ende der Zeichenfolge, die Leerzeichen enthält?

Können Sie Ihren Code anzeigen, der die Parameter übergibt? Was passierst du für die Länge der Saite - d. machst du einen trim bevor du len() machst?

+0

Ich versuchte mit der Null (in der Tat erstickt mit chr (0) - ich musste vbNullChar verwenden), aber es machte keine Unterschiede. Räume sind weg, sobald es Oracle erreicht. Der Code wird in verschiedenen Funktionen überlagert, aber ein ** ** gekürzte Version für die params Schaffung grob ist: –

+1

‚In SetParam ‘ Schaff den Parameter und hängt ihn an das Befehlsobjekt 'Geht davon aus, es ist ein Eingabeparameter Mit mGrid .Col = Spalte 'CreateParameter Drosseln, wenn Länge = 0, oder wenn Typ ist Datum und der Text ist "", daher die IIfs cmd.Parameters.Append cmd.CreateParameter (Name, DataType, AdParamInput, IIf (Len (.Text) = 0, 1, Len (.Text)), IIf (.Text = "", Null, .Text)) Ende mit 'Aufruf es Grid.SetParam cmd, eColumns.Domain, "pDomain ", adVarChar –

+0

Wie Sie sehen können, gibt es keine Trimmung vor dem Passieren der Länge. Ich kann die Parameterobjekte kurz vor der Übergabe überprüfen und die Leerzeichen sind vorhanden. –

0

Immer noch nicht genug Punkte, um einen Kommentar hinzuzufügen, jetzt, da ich dies erweitert, dass es sich als eine Lösung qualifiziert.

Oracle Objects für OLE (OO4O) ist Ihre beste Wette für die Kompatibilität mit modernen Datenbankversionen. Fügen Sie einen Verweis auf oip12.dll hinzu und probieren Sie es aus. Mein schneller Testfall zeigt, dass, wenn ich 'abc' (das waren 3 Leerzeichen) als Parameter gesendet wurde, der Sproc tatsächlich die nachfolgenden Leerzeichen enthält. Ich verwende tatsächlich oip10.dll, aber die Datenbank ist 12c. Schnelles Oracle-Beispiel, das ich verwendete.

CREATE TABLE TEMPTestTrailingSpace 
(F1 VARCHAR2(30) NOT NULL 
,F2 NUMBER(12,0) NOT NULL 
,DATEIN  DATE NOT NULL 
) ; 

create public synonym TEMPTestTrailingSpace for trace_owner.TEMPTestTrailingSpace; 
grant SELECT on TEMPTestTrailingSpace to "TRACE_USER"; 

Insert into TEMPTestTrailingSpace values ('abc',1,sysdate); 
Insert into TEMPTestTrailingSpace values ('abc  ',2,sysdate); 
Insert into TEMPTestTrailingSpace values ('abc ',3,sysdate); 
Insert into TEMPTestTrailingSpace values ('abc  ',4,sysdate); 
Insert into TEMPTestTrailingSpace values ('abd',5,sysdate); 
Insert into TEMPTestTrailingSpace values ('abd ',6,sysdate); 
Insert into TEMPTestTrailingSpace values ('abd ',7,sysdate); 

Create or Replace Procedure getTestRecord 
(
    P_PN IN VARCHAR2, 
    p_rec OUT number 
) 
IS 
BEGIN 
    SELECT f2 
    INTO p_rec 
    FROM TEMPTestTrailingSpace 
    WHERE f1 = p_pn; 
END; 
/

create public synonym getTestRecord for trace_owner.getTestRecord; 
grant execute on getTestRecord to "TRACE_USER"; 

Ich benutze einen Wrapper um den DB-Zugriff, so ist es nicht so einfach, ein Beispiel zu teilen. Damit bist du zumindest verbunden.

Public ooSession As Object 
Public ooDB As Object 

Dim ConnStr As String 
Set ooSession = New OracleInProcServer.OraSessionClass 
ConnStr = userID & "/" & password 
Set ooDB = ooSession.OpenDatabase(dataSource, ConnStr, 0&) 'dataSource = Oracle SID or alias in TNSNames.ora file 
+0

Danke für all diese Details und bestätige, dass es einen Weg gibt, dies zu tun. Ich bin in einer gesperrten Umgebung, daher kann ich OO4O kurzfristig nicht als Referenz hinzufügen. (In der Tat ist es hier so verschlossen, dass ich nicht einmal Stack Exchange unterwerfen kann - das ist alles über mein Handy!) Gut zu wissen, dass es zumindest etwas gibt, das funktioniert, wie wir es erwarten. Ich werde in OO4O schauen und anfordern, dass es den Entwicklern hier zur Verfügung gestellt wird. –

+0

Leider ist alles, was ich jemals mit klassischen VB verwendet habe, OO4O. Es ist natürlich möglich, dass es eine Lösung gibt, die den von Ihnen verwendeten ADO-Anbieter verwendet, aber ich kenne diese nicht. Es wäre jedoch leicht, einen einfachen Test zusammenzustellen, um zu beweisen, wo die Dinge scheitern (oder ob Sie erfolgreich sein können). Wenn Sie Zugriff auf ODBC-Provider haben, können Sie es auch versuchen. – topshot