0

私は少しピクルスにいます。引数を受け取り、クエリの結果を返すストアド プロシージャがあります。クエリは IN ステートメントを使用しています。

SP の構造は次のとおりです。

CREATE OR REPLACE 
PROCEDURE EXAMPLE_SP
(
   arg VARCHAR2,
   argRS1 OUT cursors.rs
)
AS 
 l_test VARCHAR2(255) := arg;

BEGIN

  OPEN argRS1 FOR
    SELECT * FROM TABLE1
    WHERE LOCATION IN (l_test);

END EXAMPLE_SP;

IN ステートメント内の値の数は変数にすることができます。IN のオプションは、UI 側で選択されたフォームのチェックボックスから取得されます。

選択したチェックボックスの値を取得するために PHP を使用しています。私はすでに値をカンマ区切りの文字列に内破しようとしました。

そのための私の論理は、クエリが次のようになるというものでした。

l_test = 'val1,  val2, val3';
SELECT * FROM TABLE1
WHERE LOCATION IN (val1, val2, val3);

しかし、それはうまくいきませんでした。どうすればよいかわかりません。建設的なコメントや提案をお寄せいただきありがとうございます。

4

4 に答える 4

0

このカンマ区切りの入力パラメーターを varchar() として追加し、次の where ステートメントを使用できます。

where (','||l_test||',' like '%,'||LOCATION||',%')

たとえば、次のようにl_test='2,3,4,5'なりLOCATION=3ます。

where (',2,3,4,5,' like '%,3,%') 

LOCATION 値がこのリストにある場合は TRUE です。

于 2012-12-05T19:04:23.863 に答える
0

あなたが選択した場所はVARCHARだと思うので、そのためには以下に示すようにリストを変換する必要があります

l_test = '''val1''||','|| ''val2''||','||''val3''';

最終的なクエリが次のようになるように

SELECT * FROM TABLE1
WHERE LOCATION IN ('val1', 'val2', 'val3');

このようなこともできます

CREATE OR REPLACE 
PROCEDURE EXAMPLE_SP
(
  arg VARCHAR2,
  argRS1 OUT cursors.rs
)
AS 
 l_test VARCHAR2(255) := arg;

 BEGIN
  l_test:=''''||replace(l_test,',',''',''')||'''';
  OPEN argRS1 FOR
    SELECT * FROM TABLE1
     WHERE LOCATION IN (l_test);

 END EXAMPLE_SP;

:私はこれをテストしていませんが、この方法であなたが望むものを達成できると思います

于 2012-12-05T19:11:12.517 に答える
0

Oracle ドキュメントの Oracle の例を使用できます: http://docs.oracle.com/cd/B28359_01/win.111/b28378/basfeat.htm#sthref207

ここを見てください - テーブルを返します: SQL プロシージャーはテーブルを返すことができますか?

そして、ここに別の例があります:

PACKAGE emp_actions IS
  TYPE EnameTabTyp IS TABLE OF emp.ename%TYPE INDEX BY BINARY_INTEGER;
  TYPE SalTabTyp IS TABLE OF emp.sal%TYPE INDEX BY BINARY_INTEGER;
  ...
  PROCEDURE hire_batch (ename_tab IN EnameTabTyp, sal_tab IN SalTabTyp, ...);
  PROCEDURE log_names (ename_tab IN EnameTabTyp);
END emp_actions;
于 2012-12-06T14:15:25.007 に答える
0

文字列操作を使用せずにこれを行います。理論的には、チェックボックスを使用しているため、現時点では SQL インジェクションのリスクはほとんどない可能性があります。変更があった場合に危険にさらされないように、最初に適切な方法を実装することをお勧めします。

2 番目の利点は、列の任意のインデックスを引き続き利用できることですlike '%...

これを行うには、テーブル関数と外部オブジェクトを利用して、「in」リストにデータを入力できます。

例として、USER_OBJECTS から OBJECT_NAME を返します。

2 つのテーブルを作成する場合:

create table tmp_test ( a number );
create table tmp_test2 ( a number );

テーブルのリストを保持するオブジェクト、または場合によっては場所。

create type t_test_object is table of varchar2(30);

次に、これがあなたの手順と同等です。SYS_REFCURSOR を返す関数です。T_TEST_OBJECT をパラメーターとして受け入れます。つまり、関数に渡す前に、まずこれを設定する必要があります。

create or replace function select_many (
       Ptest_object in t_test_object
       ) return sys_refcursor is

   l_curs sys_refcursor;

begin

   open l_curs for
    select object_name
      from user_objects
     where object_name in ( select *
                              from table(Ptest_object)
                                   );

   return l_curs;

end;

最後に、このセットアップの使用方法の例を次に示します。T_TEST_OBJECT のインスタンスに複数の値が入力される方法に注目してください。次に、このオブジェクトが関数に渡され、カーソルが返されます。最後に、値を表示するために、カーソルをループします。明らかに、カーソルを利用して TYPE を別の方法で入力したい場合があります。

SQL> declare
  2
  3     l_nested_table t_test_object := new t_test_object();
  4     l_cursor sys_refcursor;
  5     -- Used for display demonstration only.
  6     l_object_name user_objects.object_name%type;
  7
  8  begin
  9
 10     l_nested_table.extend;
 11     l_nested_table(l_nested_table.last) := 'TMP_TEST';
 12     l_nested_table.extend;
 13     l_nested_table(l_nested_table.last) := 'TMP_TEST2';
 14
 15     l_cursor := select_many(l_nested_table);
 16     
 17     loop -- Display example, not really relevant
 18        fetch l_cursor into l_object_name;
 19        exit when l_cursor%notfound;
 20        dbms_output.put_line(l_object_name);
 21     end loop;
 22
 23  end;
 24  /
TMP_TEST
TMP_TEST2

PL/SQL procedure successfully completed.
于 2012-12-06T08:43:48.537 に答える