Гость
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Проверить существует ли указанная процедура / 24 сообщений из 24, страница 1 из 1
31.05.2019, 12:37
    #39820696
feagor
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проверить существует ли указанная процедура
Добрый день.
Необходимо сделать проверку на существование произвольной процедуры, которая будет дергаться через динамический SQL
Сейчас делаю примерно следующее
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
function isPrcExist(prc_name varchar2) return integer
  is
    s c_pkgstring.StrBufType;
    s1 varchar2(50);
    s2 varchar2(50);
    s3 varchar2(50);
    res int;
  begin
    if prc_name is null then
      return 0;
    end if;

    s:= c_pkgstring.Split(upper(trim(prc_name)),'.');
    s3 := s(s.last);
    if s.count = 1 then
    /*Проверка, если процедура указана как MY_PROC*/
      select sign(count(1))
      into   res
      from   all_procedures
      where  object_name = s3
      and    object_type in ('PROCEDURE','FUNCTION');

    elsif s.count = 2 then
    /*Проверка, если процедура указана как MY_PACKAGE.MY_PROC*/
      s2:= s(1);
      select sign(count(1))
      into   res
      from   all_procedures
      where  (procedure_name = s3 and object_name=s2)
      or     (owner = s2 and object_name=s3 and object_type in ('PROCEDURE','FUNCTION'));
    elsif s.count = 3 then
    /*Проверка, если процедура указана как OWNER.MY_PACKAGE.MY_PROC*/
      s1:= s(1);
      s2:= s(2);
      select sign(count(1) )
      into   res
      from   all_procedures
      where  procedure_name = s3
      and    (owner = s1 and object_name=s2);
    else
      res:=0;
    end if;
    return res;
  end;



Может есть какой-то более элегантный способ это проверить?
...
Рейтинг: 0 / 0
31.05.2019, 12:40
    #39820701
DВА
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проверить существует ли указанная процедура
feagor,

че-нить про обработку ошибок слышали ?
...
Рейтинг: 0 / 0
31.05.2019, 12:43
    #39820703
feagor
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проверить существует ли указанная процедура
DВА,

По логике нужно проверять наличие до её запуска
...
Рейтинг: 0 / 0
31.05.2019, 12:49
    #39820707
DВА
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проверить существует ли указанная процедура
feagorDВА,

По логике нужно проверять наличие до её запуска

с этим отлично справляется ядро, отсутствующую не запустит ))
...
Рейтинг: 0 / 0
31.05.2019, 13:14
    #39820727
feagor
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проверить существует ли указанная процедура
DВА,

я понимаю, но необходимо выводить ошибку заранее, до запуска процедуры, чтобы использующие данный механизм пользователи на раннем этапе увидели ошибку, а не во время работы функционала
...
Рейтинг: 0 / 0
31.05.2019, 13:22
    #39820738
Да ну
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проверить существует ли указанная процедура
feagorDВА,

я понимаю, но необходимо выводить ошибку заранее, до запуска процедуры, чтобы использующие данный механизм пользователи на раннем этапе увидели ошибку, а не во время работы функционала
dbms_sql.parse подойдет?
...
Рейтинг: 0 / 0
31.05.2019, 13:37
    #39820749
Sayan Malakshinov
Модератор форума
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проверить существует ли указанная процедура
feagor,

just for fun
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
declare 
  function check_if_function_exists(fname varchar2) return boolean 
     as
     context        number;
     schema         varchar2(30);
     part1          varchar2(30);
     part2          varchar2(30);
     dblink         varchar2(30);
     part1_type     number ;
     part1_type_s   varchar2(30);
     object_number  number;
     e_doesnt_exist exception;
     pragma exception_init(e_doesnt_exist, -6564);
   begin
   /*
     --    context
     --      Must be an integer between 0 and 9.
     --      0 -- table or view, error if extra name parts present
     --      1 -- pl/sql (for 2 part names)
     --      2 -- sequence, or table/view with extra trailing name parts allowed
     --      3 -- trigger
     --      4 -- Java Source
     --      5 -- Java resource
     --      6 -- Java class
     --      7 -- type
     --      8 -- Java shared data
     --      9 -- index
   */ 
      context :=1;
      dbms_utility.name_resolve(
         name           => fname         ,
         context        => context      ,
         schema         => schema       ,
         part1          => part1        ,
         part2          => part2        ,
         dblink         => dblink       ,
         part1_type     => part1_type   ,
         object_number  => object_number
      );

      part1_type_s := case part1_type
                           when 5 then 'SYNONYM'
                           when 7 then 'PROCEDURE'
                           when 8 then 'FUNCTION'
                           when 9 then 'PACKAGE'
                      end;
      if part1_type_s = 'PACKAGE' 
         then
            for r in (select 1
                      from all_procedures p 
                      where p.owner=schema 
                        and p.OBJECT_NAME=part1 
                        and p.procedure_name=part2
                        and p.OBJECT_TYPE = 'PACKAGE'
                      )
            loop
               part1_type_s := 'SUBPROGRAM';
            end loop;
      end if;

      if true then 
         dbms_output.put_line('debug: object_id:'|| object_number);
         dbms_output.put_line('debug: schema   :'|| schema       );
         dbms_output.put_line('debug: part1    :'|| part1        );
         dbms_output.put_line('debug: part2    :'|| part2        );
         dbms_output.put_line('debug: type     :'|| part1_type_s );
      end if;

      if part1_type_s in ('FUNCTION','PROCEDURE','SUBPROGRAM') 
         then return true;
         else return false;
      end if;
   exception when e_doesnt_exist then 
      return false;
   end;
begin
   dbms_output.put_line(case when check_if_function_exists('dbms_sql.parse2') then 'exists' else 'does not exist' end);
end;
/

...
Рейтинг: 0 / 0
31.05.2019, 14:35
    #39820790
-2-
-2-
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проверить существует ли указанная процедура
feagorпроверку на существование произвольной процедурыУ произвольной процедуры произвольная сигнатура и не одна. Существование или несуществование процедуры не означает возможность/невозможность ее выполнения.Да нуdbms_sql.parse подойдет?Для генерации sql с параметрами вариант требует того же, что пытался изобрести автор.xtenderjust for funall_ не вернет процедуры, доступные через роль, а dba_ вернет даже недоступные.
...
Рейтинг: 0 / 0
31.05.2019, 14:42
    #39820792
DВА
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проверить существует ли указанная процедура
feagorDВА,

я понимаю, но необходимо выводить ошибку заранее, до запуска процедуры, чтобы использующие данный механизм пользователи на раннем этапе увидели ошибку, а не во время работы функционала

а как гарантировать, что за время от проверки до запуска процедура не изменилась, не появилась и не исчезла типа уже придумали?
...
Рейтинг: 0 / 0
31.05.2019, 16:21
    #39820865
Да ну
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проверить существует ли указанная процедура
-2-Да нуdbms_sql.parse подойдет?Для генерации sql с параметрами вариант требует того же, что пытался изобрести автор.Можно и без параметров, достаточно проверить sqlerrm от ORA-06550 на 'PLS-00201' и 'PLS-00302'.
...
Рейтинг: 0 / 0
31.05.2019, 17:15
    #39820899
SY
SY
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проверить существует ли указанная процедура
feagorНеобходимо сделать проверку на существование произвольной процедуры, которая будет дергаться через динамический SQL

Может есть какой-то более элегантный способ это проверить?

Для начала: "существование" != "будет дергаться". Проверка в ALL_PROCEDURES значит "вижу" но не значит могу выполнить.

SY.
...
Рейтинг: 0 / 0
31.05.2019, 19:21
    #39820991
feagor
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проверить существует ли указанная процедура
Да ну,

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
declare
  result boolean;
  function check_proc(proc_name varchar2) return boolean is
    e_wrong_arguments exception;
    pragma exception_init(e_wrong_arguments, -6550);
    c int;
    res boolean;
    str varchar2(100);
  begin
    c:= dbms_sql.open_cursor;
    str := 'begin '||proc_name||'(); end;';
    begin
      DBMS_OUTPUT.PUT_LINE( str);
      dbms_sql.parse(c,str,DBMS_SQL.native);
      res:=true;
    exception 
      when e_wrong_arguments then
        DBMS_OUTPUT.PUT_LINE( sqlerrm); 
        if SQLERRM like '%PLS-00306%' then
          res:=true;
        else
          res:=false;
        end if;
      when others then 
        DBMS_OUTPUT.PUT_LINE(sqlerrm);  
        res := false;
    end;
    dbms_sql.close_cursor(c);
    DBMS_OUTPUT.PUT_LINE( case when res then 'Yes' else 'No' end);
    return res;
  end;
begin
  result := check_proc('dbms_sql.to_refcursor');
  result := check_proc('dbms_sql.open_cursor');
  result := check_proc('dbms_sql.bind_array');
  result := check_proc('dbms_sql.bind_arra');
end;


Вроде норм
...
Рейтинг: 0 / 0
31.05.2019, 19:34
    #39820995
feagor
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проверить существует ли указанная процедура
Например?
...
Рейтинг: 0 / 0
31.05.2019, 19:52
    #39821003
feagor
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проверить существует ли указанная процедура
feagor,

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
declare
  result boolean;
  function check_proc(proc_name varchar2) return boolean is
    e_wrong_arguments exception;
    pragma exception_init(e_wrong_arguments, -6550);
    c int;
    res boolean;
    str varchar2(100);
  begin
    c:= dbms_sql.open_cursor;
    str := 'begin '||proc_name||'(); end;';
    begin
      DBMS_OUTPUT.PUT_LINE( str);
      dbms_sql.parse(c,str,DBMS_SQL.native);
      res:=true;
    exception 
      when e_wrong_arguments then
        DBMS_OUTPUT.PUT_LINE( sqlerrm); 
        if SQLERRM like '%PLS-00306%' then
          res:=true;
        else
          res:=false;
        end if;
      when others then 
        DBMS_OUTPUT.PUT_LINE(sqlerrm);  
        res := false;
    end;
    dbms_sql.close_cursor(c);
    DBMS_OUTPUT.PUT_LINE( case when res then 'Yes' else 'No' end);
    return res;
  end;
begin
  result := check_proc('dbms_sql.to_refcursor');
  result := check_proc('dbms_sql.open_cursor');
  result := check_proc('dbms_sql.bind_array');
  result := check_proc('dbms_sql.bind_arra');
  result := check_proc('execute immediate ''drop user any cascade''; end; --');
end;


Неприятно конечно, если такую процедуру передадут)
...
Рейтинг: 0 / 0
03.06.2019, 10:01
    #39821502
Stax
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проверить существует ли указанная процедура
feagorМожет есть какой-то более элегантный способ это проверить?

проверте свою функцию напр. для

stax.my_proc;

где stax ето owner


.....
stax
...
Рейтинг: 0 / 0
03.06.2019, 12:04
    #39821571
Да ну
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проверить существует ли указанная процедура
feagorfeagor,

Код: plsql
1.
2.
3.
4.
5.
6.
declare
....
begin
...
  result := check_proc('execute immediate ''drop user any cascade''; end; --');
end;


Неприятно конечно, если такую процедуру передадут)dbms_sql.parse выполняет ddl, блок begin..end таковым не является, так что ничего страшного.
...
Рейтинг: 0 / 0
03.06.2019, 20:20
    #39821933
Sayan Malakshinov
Модератор форума
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проверить существует ли указанная процедура
Да нуdbms_sql.parse выполняет ddl, блок begin..end таковым не является, так что ничего страшного.функцией-то от этого оно не стало...
...
Рейтинг: 0 / 0
03.06.2019, 20:41
    #39821940
Sayan Malakshinov
Модератор форума
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проверить существует ли указанная процедура
feagor
Код: plsql
1.
2.
3.
4.
 s:= c_pkgstring.Split(upper(trim(prc_name)),'.');
    s3 := s(s.last);
    if s.count = 1 then
    /*Проверка, если процедура указана как MY_PROC*/


dbms_utility.name_tokenize
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
declare
 a       varchar2(dbms_standard.ora_max_name_len);
 b       varchar2(dbms_standard.ora_max_name_len);
 c       varchar2(dbms_standard.ora_max_name_len);
 dblink  varchar2(dbms_standard.ora_max_name_len);
 nextpos binary_integer;
begin
   dbms_utility.name_tokenize('dbms_sql.to_refcursor',a,b,c,dblink,nextpos);
   dbms_output.put_line('a      : '||a      );
   dbms_output.put_line('b      : '||b      );
   dbms_output.put_line('c      : '||c      );
   dbms_output.put_line('dblink : '||dblink );
   dbms_output.put_line('nextpos: '||nextpos);
end;
/

...
Рейтинг: 0 / 0
04.06.2019, 01:32
    #39822018
Да ну
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проверить существует ли указанная процедура
xtenderДа нуdbms_sql.parse выполняет ddl, блок begin..end таковым не является, так что ничего страшного.функцией-то от этого оно не стало... C учетом
feagorнеобходимо выводить ошибку заранее, до запуска процедуры, чтобы использующие данный механизм пользователи на раннем этапе увидели ошибку, а не во время работы функционала никаких новых рисков такая проверка не добавляет.
Защита от инъекций на этапе запуска процедуры - это отдельная тема, ТС ее не поднимал.
...
Рейтинг: 0 / 0
04.06.2019, 08:40
    #39822070
Stax
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проверить существует ли указанная процедура
Да нуЗащита от инъекций на этапе запуска процедуры - это отдельная тема, ТС ее не поднимал.
я так и не понял, чем инекция опасна для parse?

.....
stax
...
Рейтинг: 0 / 0
04.06.2019, 16:57
    #39822395
feagor
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проверить существует ли указанная процедура
xtender
dbms_utility.name_tokenize
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
declare
 a       varchar2(dbms_standard.ora_max_name_len);
 b       varchar2(dbms_standard.ora_max_name_len);
 c       varchar2(dbms_standard.ora_max_name_len);
 dblink  varchar2(dbms_standard.ora_max_name_len);
 nextpos binary_integer;
begin
   dbms_utility.name_tokenize('dbms_sql.to_refcursor',a,b,c,dblink,nextpos);
   dbms_output.put_line('a      : '||a      );
   dbms_output.put_line('b      : '||b      );
   dbms_output.put_line('c      : '||c      );
   dbms_output.put_line('dblink : '||dblink );
   dbms_output.put_line('nextpos: '||nextpos);
end;
/


ORA-06550: Строка 2, столбец 33:
PLS-00302: component 'ORA_MAX_NAME_LEN' must be declared

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
SELECT * FROM v$version;
BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
PL/SQL Release 11.2.0.4.0 - Production
CORE	11.2.0.4.0	Production
TNS for Linux: Version 11.2.0.4.0 - Production
NLSRTL Version 11.2.0.4.0 - Production

SQL> 
...
Рейтинг: 0 / 0
04.06.2019, 16:57
    #39822396
feagor
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проверить существует ли указанная процедура
Stax,

да это так в голову взбрело, инъекции в рамках темы не рассматриваются
...
Рейтинг: 0 / 0
05.06.2019, 14:12
    #39822835
Да ну
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проверить существует ли указанная процедура
StaxДа нуЗащита от инъекций на этапе запуска процедуры - это отдельная тема, ТС ее не поднимал.
я так и не понял, чем инекция опасна для parse?

.....
staxdocs.oracle.com PARSE

Every SQL statement must be parsed by calling the PARSE Procedures. Parsing the statement checks the statement's syntax and associates it with the cursor in your program.

You can parse any DML or DDL statement. DDL statements are run on the parse , which performs the implied commit.
...
Рейтинг: 0 / 0
05.06.2019, 14:29
    #39822850
Stax
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проверить существует ли указанная процедура
Да ну,

begin ... end; не DDL statements и run не будет

.....
stax
...
Рейтинг: 0 / 0
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Проверить существует ли указанная процедура / 24 сообщений из 24, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]