Oracle 11g (Red Hat)를 사용합니다.이상한 Oracle XMLType.getClobVal() 결과
CREATE TABLE PROJECTS
(
PROJECT_ID NUMBER(*, 0) NOT NULL,
PROJECT SYS.XMLTYPE,
);
(Windows에서) 오라클 SQL Developer를 사용하여 내가 할 : : 그것은 작동
select T1.PROJECT P1 from PROJECTS T1 where PROJECT_ID = '161';
나는 XMLType을 열 간단한 일반 테이블이있다. 나는 하나의 세포를 얻는다. 나는 두 번 클릭하고 전체 XML 파일을 다운로드 할 수 있습니다. 그것은 작동
select T1.PROJECT.getClobVal() P1 from PROJECTS T1 where PROJECT_ID = '161';
을 :
은 그 때 나는 CLOB로 결과를 얻기 위해 노력했다. 나는 하나의 세포를 얻는다. 나는 두 번 클릭하고 전체 텍스트를보고 그것을 복사 할 수 있습니다. 그러나 문제가 있습니다. 클립 보드에 복사 할 때 처음 4000 자 밖에 얻을 수 없습니다. 위치 4000에 0x00 문자가 있고 나머지 CLOB가 복사되지 않은 것으로 보입니다.// ... 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가 전체 XML을 반환하지만 내 예외가 위치 4000에서 null 문자가 있기 때문에 나는이 단일 바이트를 제거 할 수 발생합니다 그러나 이것은 오히려 것 :
이를 확인하기 위해, 나는 자바에서 수표를 썼다 이상한 해결 방법.
VARCHAR2를 사용하지 않지만 어쩌면이 문제는 VARCHAR2 제한 (4000 바이트)과 관련되어 있습니다. 다른 아이디어? 이 버그가 Oracle 버그입니까 아니면 뭔가 빠졌습니까?
-------------------- 편집 --------------------
값 다음 저장 프로 시저를 사용하여 삽입 : 그것을 호출하는 데 사용
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;
자바 코드 :
try (CallableStatement cs = connection.prepareCall("{call addProject(?,?)}"))
{
cs.setInt("projectId", projectId);
cs.setCharacterStream("projectXml", new StringReader(xmlStr) , xmlStr.length());
cs.execute();
}
-------------------- 편집을. 간단한 테스트 --------------------
나는 당신의 답을 통해 모두 배웠습니다. 가장 간단한 테이블 만들기 :
create table T1 (P XMLTYPE);
XML로 두 개의 CLOB를 준비하십시오. 첫 번째는 null 문자이고 두 번째 문자는없는 문자입니다.
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>';
확인 널 (null)이 아닌 두 번째의 첫 번째 CLOB에있는 경우는 예상대로
DBMS_OUTPUT.put_line(DBMS_LOB.INSTR(P1, chr(0)));
DBMS_OUTPUT.put_line(DBMS_LOB.INSTR(P2, chr(0)));
우리는 얻을 것이다 :
14
0
봅니다 XMLTYPE에 처음 CLOB를 삽입 할 수 있습니다. 이거 작동 안 할거야. 해당 값을 삽입 할 수 없습니다.
insert into T1 (P) values (XMLTYPE(P1));
XMLTYPE에 두 번째 CLOB를 삽입하십시오. 작동합니다 :
insert into T1 (P) values (XMLTYPE(P2));
세 번째 CLOB에 삽입 된 XML을 읽으려고합니다.작동 여부 :
select T.P.getClobVal() into P3 from T1 T where rownum = 1;
null이 있는지 확인하십시오. 그것은 데이터베이스 내부에 널 (null)이없고만큼 우리는 PL/SQL 컨텍스트에있는 한에는 널 (null)이 없다는 것을 솔기
DBMS_OUTPUT.put_line(DBMS_LOB.INSTR(P3, chr(0)));
: NO 널 (null)이 없습니다. 그러나 나는 (Windows의 경우) SQL Developer에서 다음 SQL을 사용하거나 (레드햇 EE 및 Tomcat7에) 자바에서 나는 모든 반환 CLOB에에 위치 4000에 널 문자를받을 때 :
select T.P.getClobVal() from T1 T;
BR, JM
을
같은 오류 당신은 그것을'utl_file' 및 내용 모양을 어떻게 볼을 사용하여 파일에 쓸 수 있습니까? 또한'PROJECT에서 XMLType.getClobVal (PROJECT)를 선택하십시오; (기능적으로 다른 것은 아무것도 없음) – Annjawn
열은 어떻게 채워 졌습니까? 다른 클라이언트가 똑같은 것을 본다면 문제는 검색과 관련이있을 것 같지 않은가요? 값의 서브 문자열을 선택하여 null char가 여전히 거기에 있는지 확인할 수도 있습니다. –
utlfile.sql 및 prvtfile.plb를 실행했지만 여전히 utl_file (ORA-06521 : PL/SQL : 오류 매핑 기능)을 사용할 수 없습니다. 죄송합니다. – Mikosz