私はこの表を持っています:
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++)から呼び出すことになり、カーソルを返すために必要になります。
これを行うにはどうすればよいですか?私は困惑しています。
そのカーソルを返す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;
これはカーソルを返します。
可能な場合、SELECT
- StringをPL/SQLの引用符に入れないようにしてください。文字列に入れると、コンパイル時にチェックできず、使用するたびに解析する必要があります。
本当に動的SQLを使用する必要がある場合は、クエリを一重引用符で囲むことができます。
OPEN my_cursor FOR 'SELECT * FROM allitems';
この文字列は、関数が呼び出されるたびに解析する必要があります。通常は遅くなり、実行時までクエリのエラーを隠します。
ハード解析 を避けるために、可能な限りバインド変数を使用してください。
OPEN my_cursor FOR 'SELECT * FROM allitems WHERE id = :id' USING my_id;
sQL * Plusでは、REFCURSOR
変数も使用できます。
SQL> VARIABLE x REFCURSOR
SQL> DECLARE
2 V_Sqlstatement Varchar2(2000);
3 BEGIN
4 V_Sqlstatement := 'SELECT * FROM DUAL';
5 OPEN :x for v_Sqlstatement;
6 End;
7 /
ProcÚdure PL/SQL terminÚe avec succÞs.
SQL> print x;
D
-
X
カーソルをバインド変数(他のDBMSのパラメーターと呼ばれる)として宣言できる必要があります。
vincentが書いたように、次のようなことができます。
begin
open :yourCursor
for 'SELECT "'|| :someField ||'" from yourTable where x = :y'
using :someFilterValue;
end;
そのスクリプトに3つの変数をバインドする必要があります。 「someField」の入力文字列、「someFilterValue」の値、および出力変数として宣言する必要のある「yourCursor」のカーソル。
残念ながら、C++からそれをどのように行うかはわかりません。 (しかし、私にとって幸いなことに言えます。;-))
使用するアクセスライブラリに応じて、それは王室の痛みであるか、簡単な場合があります。