1

oratcl を使用した簡単な例:

テーブルの作成と簡易パッケージ

CREATE TABLE test (id INTEGER,val INTEGER);
INSERT INTO test (id,val) values (1,10);
INSERT INTO test (id,val) values (2,20);
INSERT INTO test (id,val) values (3,30);
INSERT INTO test (id,val) values (4,40);


CREATE OR REPLACE PACKAGE  tst is
  FUNCTION get_test RETURN sys_refcursor;
END; 
/

CREATE OR REPLACE  PACKAGE BODY tst is
  FUNCTION get_test  RETURN sys_refcursor
IS
   retval sys_refcursor;
BEGIN
    OPEN retval FOR SELECT * FROM test ORDER BY id;
 RETURN retval;
END;
END;
/

Tcl 関数は次のとおりです。

package require Oratcl

proc getLoginStr {} {
   set userName  "xxx"
   set password  "xxxx"
   set db        "xxx"
   append retval  $userName "/" $password "@" $db
}

set _lda ""
set _sqlH ""

proc init {} {
  global _lda
  global _sqlH
 set _lda [oralogon [getLoginStr]]
 set _sqlH [oraopen $_lda]
}

proc prepare {} {
  global _sqlH
  set Sql {
         begin
             :retval := tst.get_test();
         end;                   
 }

 ::db_ora::parseSql $_sqlH $Sql 
}

proc go {} {
  global _lda
  global _sqlH

  set curH [oraopen $_lda]
  set pv_lst [list :retval $curH] 

  orabind $_sqlH  :retval $curH
  oraexec $_sqlH

  set retval ""

  while {[orafetch $curH -datavariable row] == 0} {
    puts "row : $row" 
    lappend retval  $row
  }
return $retval
}

次のスクリプトを 1 回実行します。

source test.tcl
init
prepare
go

出力:

row : 1 10
row : 2 20
row : 3 30
row : 4 40
{1 10} {2 20} {3 30} {4 40}

go プロシージャを再実行する

go

出力:

row : 
row : 
row : 
row : 
row : 
row : 
row : 
row : 
row : 
row : 
ORA-24338: statement handle not executed

何か案は?再実行時にスクリプトが機能しなかったのはなぜですか? 私が間違っていなければ、開いているハンドル _SqlH を再利用する必要があります。

4

1 に答える 1

1

この動作を確認するのに tcl は必要ないと思います。これはプレーン SQL で再現できます。sys_refcursorによって返された を一度反復すると、それtst.get_test()を「巻き戻して」再度反復することはできません。

ref_cursors (10.2) の使用方法については、ドキュメントを参照してくださいhttp://docs.oracle.com/cd/B19306_01/appdev.102/b14261/sqloperations.htm#i7106

したがって、この現在の形式では、tclgoを再度実行した後でのみ、tcl を再度実行できますprepare

于 2012-05-21T12:27:52.827 に答える