Ich benutze Oracle 11g (auf Red Hat). Ich habe einfach normale Tabelle mit XMLType Säule:Seltsame Oracle XMLType.getClobVal() Ergebnis
CREATE TABLE PROJECTS
(
PROJECT_ID NUMBER(*, 0) NOT NULL,
PROJECT SYS.XMLTYPE,
);
Verwenden von Oracle SQL Developer (unter Windows) ich:
select T1.PROJECT P1 from PROJECTS T1 where PROJECT_ID = '161';
Es funktioniert. Ich bekomme eine Zelle. Ich kann die gesamte XML-Datei doppelklicken und herunterladen.
Dann habe ich versucht, das Ergebnis als CLOB zu erhalten:
select T1.PROJECT.getClobVal() P1 from PROJECTS T1 where PROJECT_ID = '161';
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 0x00 Zeichen an Position 4000 gibt und der Rest von CLOB wird nicht kopiert.
Um dies zu bestätigen, schrieb ich check in java:
// ... create projectsStatement
Reader reader = projectsStatement.getResultSet().getCharacterStream("P1");
BufferedReader bf = new BufferedReader(reader);
char buffer[] = new char[ 1024 ];
int count = 0;
int globalPos = 0;
while ((count = bf.read(buffer, 0, buffer.length)) > 0)
for (int i = 0; i < count; i++, globalPos++)
if (buffer[ i ] == 0)
throw new Exception("ZERO at " + Integer.toString(globalPos));
Reader liefert volle XML aber meine Ausnahme ausgelöst wird, weil es an der Position Null-Zeichen 4000. ich dieses einzelne Byte entfernen könnte, aber dies eher sein würde seltsame Problemumgehung.
Ich benutze VARCHAR2 nicht dort, 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
Wert mit folgenden gespeicherten Prozedur wurde eingefügt:
create or replace
procedure addProject(projectId number, projectXml clob) is
sqlstr varchar2(2000);
begin
sqlstr := 'insert into projects (PROJECT_ID, PROJECT) VALUES (:projectId, :projectData)';
execute immediate sqlstr using projectId, XMLTYPE(projectXml);
end;
Java-Code verwendet, es zu nennen:
try (CallableStatement cs = connection.prepareCall("{call addProject(?,?)}"))
{
cs.setInt("projectId", projectId);
cs.setCharacterStream("projectXml", new StringReader(xmlStr) , xmlStr.length());
cs.execute();
}
-------------------- bearbeiten. EINFACHER TEST --------------------
Ich werde alles verwenden, was ich aus Ihren Antworten gelernt habe. Erstellen Sie die einfachste Tabelle:
create table T1 (P XMLTYPE);
Bereiten Sie zwei CLOBs mit XMLs vor. Zuerst mit Nullzeichen, zweites ohne.
declare
P1 clob;
P2 clob;
P3 clob;
begin
P1 := '<a>';
P2 := '<a>';
FOR i IN 1..1000 LOOP
P1 := P1 || '' || chr(0);
P2 := P2 || '';
END LOOP;
P1 := P1 || '</a>';
P2 := P2 || '</a>';
Überprüfen Sie, ob null im ersten CLOB und nicht in der zweiten:
DBMS_OUTPUT.put_line(DBMS_LOB.INSTR(P1, chr(0)));
DBMS_OUTPUT.put_line(DBMS_LOB.INSTR(P2, chr(0)));
Wir werden wie erwartet erhalten:
14
0
Versuchen erste CLOB in XMLTYPE einzufügen. Es wird nicht funktionieren. Es ist nicht möglich, einen solchen Wert einzufügen:
insert into T1 (P) values (XMLTYPE(P1));
Versuchen zweite CLOB in XMLTYPE einzufügen. Es wird funktionieren:
insert into T1 (P) values (XMLTYPE(P2));
Versuchen Sie, eingefügtes XML in dritten CLOB zu lesen.Es wird funktionieren:
select T.P.getClobVal() into P3 from T1 T where rownum = 1;
Überprüfen Sie, ob dort null ist. Es gibt KEINE null:
DBMS_OUTPUT.put_line(DBMS_LOB.INSTR(P3, chr(0)));
Es Nähte, dass es keine Null innerhalb Datenbank ist und solange wir in der PL/SQL-Kontext sind, gibt es keine Null. Aber wenn ich versuche folgende SQL in SQL Developer zu verwenden (unter Windows) oder in Java (auf Red Hat EE und tomcat7) bekomme ich null Zeichen an Position 4000 in allen zurück CLOBs:
select T.P.getClobVal() from T1 T;
BR, JM
Können Sie schreiben in eine Datei 'utl_file' und sehen, wie die Inhalte aussehen? Können Sie auch versuchen '' XMLType.getClobVal (PROJECT) von PROJECTS auszuwählen; '? (Nichts funktionell anders aber) – Annjawn
Wie wurde die Kolumne bevölkert? Sind Sie sicher, dass das Problem beim Abruf liegt - klingt unwahrscheinlich, wenn verschiedene Kunden dasselbe sehen. Sie können auch eine Teilzeichenfolge des Werts auswählen und prüfen, ob das Nullzeichen noch vorhanden ist. –
Ich habe utlfile.sql und prvtfile.plb ausgeführt, aber ich kann immer noch nicht utl_file (ORA-06521: PL/SQL: Fehler-Mapping-Funktion), sorry. – Mikosz