Ich benutze Oracle 11g (auf Red Hat). Ich habe eine einfache reguläre Tabelle mit XMLType-Spalte:
%Vor%Mit Oracle SQL Developer (unter Windows) mache ich:
%Vor%Es funktioniert. Ich bekomme eine Zelle. Ich kann die gesamte XML-Datei doppelklicken und herunterladen.
Dann habe ich versucht, das Ergebnis als CLOB zu bekommen:
%Vor%Es funktioniert. Ich bekomme eine Zelle. Ich kann doppelklicken und den ganzen Text sehen und kopieren. Aber es gibt ein Problem. Wenn ich es in die Zwischenablage kopiere, bekomme ich nur die ersten 4000 Zeichen. Es scheint, dass es an der Position 4000 0x00 Zeichen gibt und der Rest von CLOB nicht kopiert wird.
Um dies zu bestätigen, schrieb ich einchecken in Java:
%Vor%Reader gibt vollständiges XML zurück, aber meine Ausnahme wird ausgelöst, weil an Position 4000 ein Nullzeichen vorhanden ist. Ich könnte dieses einzelne Byte entfernen, aber das wäre eine seltsame Problemumgehung.
Ich verwende VARCHAR2 dort nicht, aber vielleicht hängt dieses Problem irgendwie mit VARCHAR2 Begrenzung (4000 Bytes) zusammen? Irgendwelche anderen Ideen? Ist das ein Oracle Bug oder fehlt mir etwas?
-------------------- Bearbeiten --------------------
Der Wert wurde mithilfe der folgenden gespeicherten Prozedur eingefügt:
%Vor%Java-Code zum Aufruf:
%Vor%-------------------- Bearbeiten. EINFACHER TEST --------------------
Ich werde alles verwenden, was ich aus deinen Antworten gelernt habe. Erstellen Sie die einfachste Tabelle:
%Vor%Bereiten Sie zwei CLOBs mit XMLs vor. Zuerst mit Nullzeichen, zweites ohne.
%Vor%Überprüfen Sie, ob sich null im ersten CLOB und nicht im zweiten befindet:
%Vor%Wir werden wie erwartet kommen:
%Vor%Versuchen Sie, das erste CLOB in XMLTYPE einzufügen. Es wird nicht funktionieren. Es ist nicht möglich, einen solchen Wert einzufügen:
%Vor%Versuchen Sie, das zweite CLOB in XMLTYPE einzufügen. Es wird funktionieren:
%Vor%Versuchen Sie, eingefügtes XML in den dritten CLOB einzulesen. Es wird funktionieren:
%Vor%Überprüfen Sie, ob null ist. Es gibt KEINE null:
%Vor%Es scheint, dass es in der Datenbank keinen Nullwert gibt und solange wir uns im PL / SQL-Kontext befinden, gibt es keinen Nullwert. Aber wenn ich versuche, folgende SQL in SQL Developer (unter Windows) oder in Java (unter Red Hat EE und Tomcat7) zu verwenden, bekomme ich in allen zurückgegebenen CLOBs ein Nullzeichen an der Position 4000:
%Vor%BR, JM
es ist kein Oracle-Bug (es speichert und ruft das \ 0 einfach gut. Es ist ein Client / Windows-Bug (Unterschiedliche Clients verhalten sich anders in Bezug auf "NUL" wie Windows)
chr (0) ist wirklich kein gültiges Zeichen in Nicht-Blobs (ich bin gespannt, wie Sie den XMLType überhaupt dazu bringen, ihn überhaupt zu akzeptieren, da er normalerweise nicht parsen würde).
\ 0 wird in C verwendet, um das Ende einer Zeichenfolge (NUL-Terminator) zu bezeichnen, und einige GUIs würden die Verarbeitung der Zeichenfolge an diesem Punkt beenden. Zum Beispiel:
%Vor%doch Kröte scheitert kläglich daran:
sql Entwickler geht es besser, wie Sie es sehen können:
Aber wenn Sie es kopieren, kopiert die Zwischenablage es nur bis zum Nullzeichen. Dieser Copy-Paste-Fehler ist zwar kein SQL-Entwicklerfehler, aber ein Problem mit der Windows-Zwischenablage, das es NUL nicht erlaubt, korrekt einzufügen.
Sie sollten nur replace(T1.PROJECT.getClobVal(), chr(0), null)
, um dies zu umgehen, wenn Sie sql Entwickler / Windows-Zwischenablage verwenden.
Ich habe dieses Problem auch genau so erlebt, wie es von Mikosz beschrieben wurde (ein zusätzliches "NUL" -Zeichen um das 4000. Zeichen herum, wenn ich meinen XMLType-Wert als Clob ausgab). Während ich in SQLDeveloper herumspielte, bemerkte ich eine interessante Problemumgehung. Ich habe versucht, die Ausgabe meines XMLType zu sehen, aber ich war es leid, zum 4000. Zeichen zu scrollen, also begann ich, die Clob-Ausgabe in einen substr zu schreiben (...). Zu meiner Überraschung verschwand das Thema tatsächlich. Ich habe dies in meine Java-App integriert und bestätigt, dass das Problem nicht mehr vorhanden war und mein Clob ohne das zusätzliche Zeichen abgerufen werden konnte. Ich weiß, dass dies keine ideale Problemumgehung ist, und ich bin mir immer noch nicht sicher, warum es funktioniert (würde mich freuen, wenn mir jemand das erklären könnte), aber hier ist ein abgekürztes Beispiel dafür, was ich gerade funktioniere:
> %Vor% Einfach genug, um zu überprüfen, ob es der .getClobVal()
-Aufruf ist oder nicht - führen Sie einen INSTR
-Test in PL / SQL (nicht Java) auf Ihrem resultierenden CLOB durch, um zu sehen, ob CHR(0)
existiert oder nicht.
Wenn nicht, dann würde ich mit dem Finger auf Ihre Oracle-Client-Installation zeigen.