動的SQLを実行するOracle PL/SQL匿名ブロックから結果セット/カーソルを返すにはどうすればいいですか? 質問する

動的SQLを実行するOracle PL/SQL匿名ブロックから結果セット/カーソルを返すにはどうすればいいですか? 質問する

次のような表があります:

ALLITEMS
---------------
ItemId  | Areas
---------------
1       | EAST
2       | EAST
3       | SOUTH
4       | WEST

DDL:

drop table allitems;

Create Table Allitems(ItemId Int,areas Varchar2(20));
Insert Into Allitems(Itemid,Areas) Values(1,'east');
Insert Into Allitems(ItemId,areas) Values(2,'east');
insert into allitems(ItemId,areas) values(3,'south');
insert into allitems(ItemId,areas) values(4,'east');

MSSQL では、動的 SQL からカーソルを取得するには、次のようにします。

DECLARE @v_sqlStatement VARCHAR(2000);
SET @v_Sqlstatement = 'SELECT * FROM ALLITEMS';
EXEC (@v_sqlStatement); --returns a resultset/cursor, just like calling SELECT 

Oracle では、PL/SQL ブロックを使用する必要があります。

SET AUTOPRINT ON;
DECLARE
 V_Sqlstatement Varchar2(2000);
 outputData SYS_REFCURSOR;
BEGIN
 V_Sqlstatement := 'SELECT * FROM ALLITEMS';
 OPEN outputData for v_Sqlstatement; 
End;
--result is : anonymous block completed

**しかし、私が得るのは

「匿名ブロックが完了しました」。

カーソルを戻すにはどうしたらいいでしょうか?

AUTOPRINT を実行すると、REFCURSOR 内の情報が印刷されることはわかっています (上記のコードでは印刷されませんが、これは別の問題です)

この動的 SQL をコード (ODBC、C++) から呼び出して、カーソルを返す必要があります。方法は?

ベストアンサー1

そのカーソルを返す PL/SQL 関数を記述できます (または、これに関連するコードがさらにある場合は、その関数をパッケージに配置することもできます)。

CREATE OR REPLACE FUNCTION get_allitems
  RETURN SYS_REFCURSOR
AS
  my_cursor SYS_REFCURSOR;
BEGIN
  OPEN my_cursor FOR SELECT * FROM allitems;
  RETURN my_cursor;
END get_allitems;

これによりカーソルが返されます。

可能な場合は、PL/SQL で -String を引用符で囲まないようにしてくださいSELECT。文字列に入れると、コンパイル時にチェックできなくなり、使用するたびに解析が必要になります。


動的 SQL を本当に使用する必要がある場合は、クエリを一重引用符で囲むことができます。

  OPEN my_cursor FOR 'SELECT * FROM allitems';

この文字列は関数が呼び出されるたびに解析する必要があり、通常は遅くなり、実行時までクエリ内のエラーが隠れてしまいます。

回避するために、可能な場合は必ずバインド変数を使用してください。ハード解析:

  OPEN my_cursor FOR 'SELECT * FROM allitems WHERE id = :id' USING my_id;

おすすめ記事