Выберите процедуру в оракуле против любого столбца - PullRequest
0 голосов
/ 23 октября 2019

Я пытаюсь написать процедуру, которая может принимать имя и значение столбца в качестве входного параметра и выбирать все столбцы из таблицы по значению и имени столбца, которое передается пользователем.

Любойпомощь?

Ответы [ 3 ]

0 голосов
/ 23 октября 2019

Не используйте динамический SQL или, если вам нужно использовать динамический SQL, либо внесите белый список имен столбцов, либо выполните некоторую проверку имени столбца, чтобы убедиться, что это действительный идентификатор SQL.

Бездинамический SQL:

CREATE PROCEDURE test (
  in_column_name IN  VARCHAR2,
  in_value       IN  VARCHAR2,
  out_cursor     OUT SYS_REFCURSOR
)
IS
BEGIN
  OPEN out_cursor FOR
    SELECT *
    FROM   employees
    WHERE  CASE UPPER( in_column_name )
           WHEN 'FIRST_NAME' THEN first_name
           WHEN 'LAST_NAME'  THEN last_name
           WHEN 'SALARY'     THEN TO_CHAR( salary )
           WHEN 'DEPARTMENT' THEN department
           ELSE                   NULL
           END
           = in_value;
END;
/

С динамическим SQL - внесите белый список в столбцы и используйте переменную связывания для значения:

CREATE PROCEDURE test2 (
  in_column_name IN  VARCHAR2,
  in_value       IN  VARCHAR2,
  out_cursor     OUT SYS_REFCURSOR
)
IS
BEGIN
  IF UPPER( in_column_name ) NOT IN ( 'FIRST_NAME', 'LAST_NAME', 'DEPARTMENT', 'SALARY' )
  THEN
    raise_application_error( -20000, 'Invalid Column Name' );
  END IF;
  OPEN out_cursor FOR
    'SELECT * FROM employees WHERE ' || in_column_name || ' = :value'
    USING in_value;
END;
/

С динамическим SQL - используйте DBMS_ASSERT для проверки имени столбцаи переменная связывания для значения:

CREATE PROCEDURE test3 (
  in_column_name IN  VARCHAR2,
  in_value       IN  VARCHAR2,
  out_cursor     OUT SYS_REFCURSOR
)
IS
BEGIN
  OPEN out_cursor FOR
    'SELECT * FROM employees WHERE ' || DBMS_ASSERT.SIMPLE_SQL_NAME( in_column_name ) || ' = :value'
    USING in_value;
END;
/

дБ <> fiddle

0 голосов
/ 23 октября 2019
BELOW CODE CAN BE USED TO SEARCH A COLUMN NAME AND VALUE IN ALL DATABASE. 

CREATE OR REPLACE PROCEDURE P2_CLOB_INSERT(P_SNO NUMBER, P_COLUMN_NAME VARCHAR2, KEY_COLUMN_VALUE VARCHAR2,  P_OWNER VARCHAR2, P_TABLENAME VARCHAR2) IS
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN 
    INSERT INTO QRY_STRING_TABLE VALUES (P_SNO, V_STR);
    COMMIT;
EXCEPTION
WHEN OTHERS THEN
    ROLLBACK;
END;

CREATE OR REPLACE PROCEDURE P2_CLOB_DELETE IS
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN 
    DELETE FROM QRY_STRING_TABLE;
    COMMIT;
EXCEPTION
WHEN OTHERS THEN
    ROLLBACK;
END;


CREATE OR REPLACE PROCEDURE P2_CLOB_UPDATE(P_SNO NUMBER) IS
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN 
    UPDATE QRY_STRING_TABLE
    SET STR = REPLACE (STR,' UNION ' ,'') 
    WHERE SNO =P_SNO ;
    COMMIT;
EXCEPTION
WHEN OTHERS THEN
    ROLLBACK;
END;

------------------

create or replace function f2_CLOB (p_column_name varchar2, p_column_value varchar2) return sys_refcursor 
is
    c1 sys_refcursor;
    str VARCHAR2(4000);
    lv_cnt number := 0;
begin
    P2_CLOB_DELETE;
    for all_tabs in (select rownum sno, a.owner ,a.table_name,a.column_name column_name
                          ,(select b.column_name from all_tab_cols b where b.table_name = a.table_name and b.column_id = 1 and a.owner = b.owner) id_column_name
                                    from ALL_tab_columns a where column_name = p_column_name

      ) loop
            lv_cnt := lv_cnt + 1;
             str := 'select ' || CHR(39)  || all_tabs.id_column_name || CHR(39)  || ' as PRIMARYKEY_COLUMN_NAME, ' 
                                  || 'TO_CHAR(' || all_tabs.id_column_name || ')' || ' AS PRIMARYKEY_COLUMN_VALUE,' 
                                  || CHR(39)  || all_tabs.column_name || CHR(39)  || ' as SEARCHED_COLUMN_NAME, ' 
                                  || 'TO_CHAR(' || p_column_name || ')' || ' as SEARCHED_column_value, ' 
                                  ||  CHR(39)  || all_tabs.owneR || CHR(39)  || ' as owner, ' 
                                  || CHR(39)  || all_tabs.table_name || CHR(39)  || ' as tablename ' 
                                  || '  from ' || all_tabs.OWNER || '.' || all_tabs.table_name || ' Where ' || all_tabs.column_name || ' = ' || p_column_value ||  ' UNION ' || CHR(10);
            P2_CLOB_INSERT (lv_cnt,STR);
     end loop;
        P2_CLOB_UPDATE(lv_cnt) ;
     --dbms_output.put_line(LENGTH(str));
     open c1 for SELECT STR FROM QRY_STRING_TABLE ORDER BY SUBSTR(STR,-6) DESC ;
     return c1;
end;

-----------------------

SELECT f2_CLOB('SEARCH_COLUMN_NAME','SEARCH_VALUE') FROM DUAL
0 голосов
/ 23 октября 2019

Для этого потребуется какой-то динамический SQL . Одним из вариантов является использование refcursor, например

SQL> create or replace function f_test (par_column in varchar2, par_value in varchar2)
  2    return sys_refcursor
  3  is
  4    l_column user_tab_columns.column_name%type;
  5    rc sys_refcursor;
  6  begin
  7    select column_name
  8      into l_column
  9      from user_tab_columns
 10      where table_name = 'EMP'
 11        and column_name = upper(par_column);
 12
 13    open rc for 'select * from emp where ' || par_column ||
 14                ' = :column_value' using par_value;
 15    return rc;
 16  exception
 17    when no_data_found then
 18      raise_application_error(-20000, 'Invalid column name');
 19  end;
 20  /

Function created.

SQL> select f_test('deptno', '10') from dual;

F_TEST('DEPTNO','10'
--------------------
CURSOR STATEMENT : 1

CURSOR STATEMENT : 1

     EMPNO ENAME      JOB              MGR HIREDATE                   SAL       COMM     DEPTNO
---------- ---------- --------- ---------- ------------------- ---------- ---------- ----------
      7782 CLARK      MANAGER         7839 1981-06-09 00:00:00       2450                    10
      7839 KING       PRESIDENT            1981-11-17 00:00:00       5000                    10
      7934 MILLER     CLERK           7782 1982-01-23 00:00:00       1300                    10
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...