2016-12-17 8 views
1

Я пытаюсь отправить содержимое таблицы xmltype на вставку с помощью httpRequest, для этого мне нужно преобразовать его в varchar, чтобы передать его в POST.Преобразование XMLTYPE в VARCHAR

Вот моя вставка:

Insert into CC.MOVIE (SYS_NC_ROWINFO$) values ('<movie> 
     <id>217530</id> 
     <title>Midnight Limited</title> 
     <originalTitle>Midnight Limited</originalTitle> 
     <release_date>1940-03-20</release_date> 
     <status>3</status> 
     <vote_average>0</vote_average> 
     <vote_count>0</vote_count> 
     <runtime>0</runtime> 
     <certification/> 
     <budget>61</budget> 
     <tagline>DEATH RIDES THE RAILS!                                      </tagline> 
     <genres> 
     <genre> 
      <idGenre>12</idGenre> 
     </genre> 
     <genre> 
      <idGenre>28</idGenre> 
     </genre> 
     <genre> 
      <idGenre>80</idGenre> 
     </genre> 
     </genres> 
     <actors> 
     <actor> 
      <idActor>32218</idActor> 
      <characterName>Prof. Van Dillon</characterName> 
     </actor> 
     <actor> 
      <idActor>87545</idActor> 
      <characterName>Joan Marshall</characterName> 
     </actor> 
     <actor> 
      <idActor>90336</idActor> 
      <characterName>Val Lennon</characterName> 
     </actor> 
     <actor> 
      <idActor>120708</idActor> 
      <characterName>Capt. Harrigan</characterName> 
     </actor> 
     </actors> 
     <directors> 
     <director> 
      <idDirector>120796</idDirector> 
     </director> 
     </directors> 
    </movie> 
    '); 

и мой триггер:

create or replace TRIGGER movie_insert 

     AFTER INSERT ON MOVIE 
     FOR EACH ROW 
     DECLARE 
     doc XMLType; 
     req utl_http.req; 
     res utl_http.resp; 
     url varchar2(4000) := 'http://10.0.2.2:8088/VerifActeur/VerifActeur'; 
     --name varchar2(4000); 
     buffer varchar2(5000); 
     BEGIN 
    SELECT 
     EXTRACTVALUE(:new.object_value, '/movie/text()') 
    INTO buffer 
    FROM DUAL; 

    --Select CAST(:new.object_value AS VARCHAR2(5000)) into buffer from dual; 
     -- buffer := :new.object_value.getStringVal(); 
     --doc := :new.sys_nc_rowinfo$; 
     --buffer:= :new.object_value.extract('/movie/text()').getStringVal(); 
     dbms_output.put_line(buffer); 

     req := utl_http.begin_request(url, 'POST'); 
     --utl_http.set_header(req, 'user-agent', 'mozilla/4.0'); 
     utl_http.set_header(req, 'content-type', 'text/xml'); 
     utl_http.set_header(req, 'Content-Length', length(buffer)); 

     utl_http.write_text(req, buffer); 

     res := utl_http.get_response(req); 
     -- process the response from the HTTP call 
     begin 
      loop 
      utl_http.read_line(res, buffer); 
      dbms_output.put_line(buffer); 
      end loop; 
      utl_http.end_response(res); 
     exception 
      when utl_http.end_of_body 
      then 
      utl_http.end_response(res); 
     end; 
     utl_http.end_request(req); 
     END; 

Но ценность экстракта вывода изображения ничего, и в этом случае запрос не вдавливать (вероятно, из-за возвращения длины ничего). И другие методы возвращают исключения.

ответ

1

Ваш movie узел не содержит текста, он содержит только дочерние узлы; поэтому верно для extractvalue для возврата null. Кстати, эта функция устарела от 11 г. Ваша вставка и триггер в настоящее время смотрят на разные столбцы, которые могут не помогать, но это может быть ошибкой в ​​вопросе, а не с вашим фактическим кодом.

Вы можете использовать XMLSerialize для преобразования значения XMLType в строку, либо VARCHAR или (если значение слишком велико для этого типа данных) в CLOB, что-то вроде:

SELECT XMLSerialize(DOCUMENT :new.object_value AS VARCHAR2(4000) NO INDENT) 
INTO buffer 
FROM dual; 

Вы не сказал, какую версию Oracle вы используете. До 12c контекст SQL означает, что вы ограничены 4000 символами, но ваш буфер объявлен как 5000. Используя no indent, вы можете удалить лишние пробелы, чтобы это не было проблемой, но вам, возможно, придется использовать CLOB.

С таблицей фиктивных таблиц и вставкой в ​​тот же столбец XMLType триггер запрашивает (почему вы используете имена столбцов из таблиц словаря данных? Надеемся, вы фактически не добавляете триггеры в словарь данных?) И комментируете из HTTP-бит для теперь, это производит:

Table MOVIE created. 

Trigger MOVIE_INSERT compiled 

<movie><id>217530</id><title>Midnight Limited</title><originalTitle>Midnight Limited</originalTitle><release_date>1940-03-20</release_date><status>3</status><vote_average>0</vote_average><vote_count>0</vote_count><runtime>0</runtime><certification/><budget>61</budget><tagline>DEATH RIDES THE RAILS!                                      </tagline><genres><genre><idGenre>12</idGenre></genre><genre><idGenre>28</idGenre></genre><genre><idGenre>80</idGenre></genre></genres><actors><actor><idActor>32218</idActor><characterName>Prof. Van Dillon</characterName></actor><actor><idActor>87545</idActor><characterName>Joan Marshall</characterName></actor><actor><idActor>90336</idActor><characterName>Val Lennon</characterName></actor><actor><idActor>120708</idActor><characterName>Capt. Harrigan</characterName></actor></actors><directors><director><idDirector>120796</idDirector></director></directors></movie> 


1 row inserted. 

Делать это в триггере выглядит неуклюжим, даже если dbms_output только там для отладки. Например, что произойдет, если вызов http не удался - должна ли новая строка по-прежнему храниться, или это исключение, отфильтрованное до вызывающего абонента и откат, как вы хотите/ожидаете? Не будет ясно, что происходит с тем, кто делает вставку. Возможно, было бы более надежно вставлять вставку и http-вызов в хранимую процедуру, чтобы логика была вместе и легко видна, вместо того чтобы полагаться на побочные эффекты через триггеры. Затем заблокируйте прямой доступ к таблице (для вставки в любом случае) и разрешите только процедуру обертки. Просто мысль ...

+0

Я попытался использовать XMLSerialize, как вы посоветовали, но я получил эту ошибку: «ORA-30991:» не может использовать DOM для добавления специального атрибута к родительскому элементу схемы »' –

+0

Из этого запроса в триггере ? Я не знаю, как это сделать. К сожалению, я не могу проверить это на монете или воссоздать эту ошибку. Какую версию Oracle вы используете? Хм, вы вставляете XML в 'SYS_NC_ROWINFO $', поэтому откуда взялось 'objct_value'? –

 Смежные вопросы

  • Нет связанных вопросов^_^