0

(ユーザー入力からの)コンマ区切りの文字列のリストがあり、「not in where句」を使用して、ネストされたSQLブロックのpl/sqlストアド関数のパラメータとしてこのリストを使用したいと思います。

私はそれを機能させるためのエレガントな方法を見つけることができません...

それが私が考えていることです:

CREATE TABLE example ( somevalue VARCHAR(36) NOT NULL);
--
INSERT INTO example VALUES ('value1');
INSERT INTO example VALUES ('value2');
INSERT INTO example VALUES ('value3');
--
SELECT * FROM example;
--
CREATE OR REPLACE
  FUNCTION resultmaker(
      ignoreList IN VARCHAR2)
    RETURN VARCHAR2
  IS
    result VARCHAR2(4000);
  BEGIN
    result  := 'Here is my calculated result, using ignorelist=' || ignoreList || ':'     || CHR(10);
    FOR rec IN
    (SELECT DISTINCT somevalue
    FROM example
    WHERE somevalue NOT IN resultmaker.ignoreList -- here's my issue, the NOT IN     clause using the parameter value
    )
    LOOP
      result := result || 'not in ignorelist: ' || rec.somevalue || CHR(10);
    END LOOP;
    result := result || '.' || CHR(10);
    --
    RETURN result;
  END resultmaker;
  /
--
-- simulate function call with user input 'value2, value3'
SELECT resultmaker('value2, value3') FROM dual; -- doesn't work  
--
DROP TABLE example;
DROP FUNCTION resultmaker;
4

5 に答える 5

1

のようなパラメータを渡し'"value2","value3"'て、ステートメントで二重引用符をのような一重引用符に置き換えてくださいREPLACE(@Param1,'"','''')

関数の呼び出し: SELECT * FROM Function1('"value2","value3"')

内部機能: NOT IN REPLACE(@Param1,'"','''')

于 2015-10-14T15:39:59.150 に答える
0

いずれの場合も、その入力を解析する必要があります。PL / SQLには組み込みの文字列トークナイザーがないため(少なくとも私はそれを見つけることができませんでした)、これらのオプションを調べてみてください。

http://blog.tanelpoder.com/2007/06/20/my-version-of-sql-string-to-table-tokenizer/

PL / SQLにはJavaと同等のStringTokenizerがありますか?

文字列を解析した後、次のような新しい文字列を作成できます。

not_in_statement varchar2(1000);
CURSOR c1 IS select token from tokenized_strings_table;
BEGIN
    not_in_statement := '('
    FOR rec IN c1 LOOP
        not_in_statement := not_in_statement || '''||rec.token||'''||','
    END LOOP
    not_in_statement := not_in_statement||')'
END

SELECT DISTINCT somevalue
FROM example
WHERE somevalue NOT IN not_in_statement

動的SQLにする必要があるかもしれませんが、試す時間がありませんでした。

于 2013-01-04T13:23:08.963 に答える
0

上記の元の質問に動的SQLを使用したソリューションは次のとおりです。

CREATE TABLE example ( somevalue VARCHAR(36) NOT NULL);
--
INSERT INTO example VALUES ('value1');
INSERT INTO example VALUES ('value2');
INSERT INTO example VALUES ('value3');
--
SELECT * FROM example;
--
CREATE OR REPLACE
  FUNCTION resultmaker(
      ignoreList IN VARCHAR2)
    RETURN VARCHAR2
  IS
    result VARCHAR2(4000);
    example_cursor sys_refcursor;
    rec example.somevalue%type;
  BEGIN
    result := 'Here is my calculated result, using ignorelist=' || ignoreList || ':' || CHR(10);
    OPEN example_cursor FOR ( 'SELECT DISTINCT somevalue FROM example WHERE somevalue NOT IN (' || ignoreList || ')' );
    FETCH example_cursor INTO rec;
    WHILE example_cursor%found
    LOOP
      result := result || 'not in ignorelist: ' || rec || CHR(10);
      FETCH example_cursor INTO rec;
    END LOOP;
    CLOSE example_cursor;
    result := result || '.' || CHR(10);
    --
    RETURN result;
  END resultmaker; 
/
--
-- simulate function call with user input 'value2', 'value3'
SELECT resultmaker('''value2'', ''value3''') FROM dual;
--
DROP TABLE example;
DROP FUNCTION resultmaker;
于 2013-01-04T15:10:38.857 に答える
0

古典的でおそらく正しい解決策は、PL/SQL表を使用してそれをプラメータとして渡すことです...

于 2013-01-04T21:29:59.693 に答える
0

値の文字列を取得し、それらのIN句を動的に作成することに関して、asktom.oracle.comにはいくつかの優れた解決策があります。

http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:210612357425

于 2013-01-05T05:18:48.583 に答える