次のような表があります:
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;