0

目標は、そのような機能を備えた関数を作成するために、ユーザーが提供したトークンから列名を照会できる Oracle 関数を作成することです。

select cols_like('%e%') from table

これが私が現在いるポイントです

CREATE OR REPLACE Function COLS_LIKE 
(v_search in VARCHAR2, v_table in VARCHAR2) 
RETURN VARCHAR
IS
    TYPE r_cursor IS REF CURSOR;
    c_emp         r_cursor;
    crs_cols      VARCHAR(255);
    column_list   VARCHAR(1000);
BEGIN    
    OPEN c_emp FOR 
        'select COLUMN_NAME from cols 
         where TABLE_NAME = ''' || v_table || ''' 
         and column_name like ''' || v_search || ''''; 
LOOP
    FETCH c_emp INTO crs_cols;

    EXIT WHEN c_emp%NOTFOUND;

    if column_list IS NULL THEN 
        column_list := crs_cols;
    else 
        column_list := column_list || ', ' || crs_cols;
    end if;
END LOOP; 

RETURN column_list;

END;

このような関数を呼び出す場所

Declare
    tests VARCHAR(100);
    sql_stmt VARCHAR2(200);
begin
    tests := COLS_LIKE('%E%', 'table');
    DBMS_OUTPUT.PUT_LINE(tests);
-- OR
    sql_stmt := 'select ' || COLS_LIKE('%E%', 'table') || ' from table';
    DBMS_OUTPUT.PUT_LINE(sql_stmt);
end;

最終的な目標は、このようなものになります

select COLS_LIKE('%E%', 'table') from table;

この関数を正しく適用できるように、関数にどのような変更を加えることができるか、またはどのように呼び出しているか。

4

2 に答える 2

2

なぜそのようなことをしたいのか私にはわかりませんが、開いているカーソルを PL/SQL にかなり簡単に返すことができます。

create or replace function cols_like (
     PTable in varchar2
   , PColumn in varchar2
     ) return sys_refcursor

   l_cols varchar2(32767);
   c_curs sys_refcursor;

begin

   select listagg(column_name, ', ') within group (order by column_id)
     into l_cols
     from user_tab_cols
    where table_name = upper(Ptable)
      and column_name like '%' || upper(PColumn) || '%'
          ;

   open c_curs for '
     select ' || l_cols || '
       from ' || Ptable;

   return c_curs;

end;
/

これを標準の SQL ステートメントに戻すのは、はるかに困難です。これは、この関数を選択する際に、1列分のデータしか選択していないためです。N列を選択できるようにする必要があるため、動的に作成されたネストされたテーブルを返す必要があります。

可能だと確信しています。しかし、これをやろうとする前に、なぜそれをやっているのかを考えてください。最終目標を述べるのではなく、実際の問題は何かを述べる質問をしてください。もっと簡単な解決策がある可能性があります。

于 2013-07-29T21:09:41.720 に答える