2016-12-17 13 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を返すのが正しいです。この関数は、偶然にも11gから非難されています。挿入とトリガーは現在、異なる列を参照していますが、これは助けにはならないかもしれませんが、実際のコードではなく疑問に間違いかもしれません。

(値がそのデータ型に対して大きすぎる場合)あなたはどちらかvarchar型や、文字列にXMLType値を変換するために、CLOBをXMLSerializeを使用することができ、のようなもの:あなたが持っていない

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

トリガー内のそのクエリから?私はどのようにか分からない。私は残念ながらそれをmonentでこれをテストすることはできません、またはそのエラーを再現します。どのOracleのバージョンを使用していますか?うーん、XMLを 'SYS_NC_ROWINFO $'に挿入しているので、 'objct_value'はどこから来ますか? –

関連する問題