powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Проверить существует ли указанная процедура
24 сообщений из 24, страница 1 из 1
Проверить существует ли указанная процедура
    #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
Проверить существует ли указанная процедура
    #39820701
Фотография DВА
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
feagor,

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

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

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

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

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

я понимаю, но необходимо выводить ошибку заранее, до запуска процедуры, чтобы использующие данный механизм пользователи на раннем этапе увидели ошибку, а не во время работы функционала
dbms_sql.parse подойдет?
...
Рейтинг: 0 / 0
Проверить существует ли указанная процедура
    #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
Проверить существует ли указанная процедура
    #39820790
Фотография -2-
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
feagorпроверку на существование произвольной процедурыУ произвольной процедуры произвольная сигнатура и не одна. Существование или несуществование процедуры не означает возможность/невозможность ее выполнения.Да нуdbms_sql.parse подойдет?Для генерации sql с параметрами вариант требует того же, что пытался изобрести автор.xtenderjust for funall_ не вернет процедуры, доступные через роль, а dba_ вернет даже недоступные.
...
Рейтинг: 0 / 0
Проверить существует ли указанная процедура
    #39820792
Фотография DВА
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
feagorDВА,

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

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

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

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

SY.
...
Рейтинг: 0 / 0
Проверить существует ли указанная процедура
    #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
Проверить существует ли указанная процедура
    #39820995
feagor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Например?
...
Рейтинг: 0 / 0
Проверить существует ли указанная процедура
    #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
Проверить существует ли указанная процедура
    #39821502
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
feagorМожет есть какой-то более элегантный способ это проверить?

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

stax.my_proc;

где stax ето owner


.....
stax
...
Рейтинг: 0 / 0
Проверить существует ли указанная процедура
    #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
Проверить существует ли указанная процедура
    #39821933
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
Да нуdbms_sql.parse выполняет ddl, блок begin..end таковым не является, так что ничего страшного.функцией-то от этого оно не стало...
...
Рейтинг: 0 / 0
Проверить существует ли указанная процедура
    #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
Проверить существует ли указанная процедура
    #39822018
Да ну
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
xtenderДа нуdbms_sql.parse выполняет ddl, блок begin..end таковым не является, так что ничего страшного.функцией-то от этого оно не стало... C учетом
feagorнеобходимо выводить ошибку заранее, до запуска процедуры, чтобы использующие данный механизм пользователи на раннем этапе увидели ошибку, а не во время работы функционала никаких новых рисков такая проверка не добавляет.
Защита от инъекций на этапе запуска процедуры - это отдельная тема, ТС ее не поднимал.
...
Рейтинг: 0 / 0
Проверить существует ли указанная процедура
    #39822070
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Да нуЗащита от инъекций на этапе запуска процедуры - это отдельная тема, ТС ее не поднимал.
я так и не понял, чем инекция опасна для parse?

.....
stax
...
Рейтинг: 0 / 0
Проверить существует ли указанная процедура
    #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
Проверить существует ли указанная процедура
    #39822396
feagor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Stax,

да это так в голову взбрело, инъекции в рамках темы не рассматриваются
...
Рейтинг: 0 / 0
Проверить существует ли указанная процедура
    #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
Проверить существует ли указанная процедура
    #39822850
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Да ну,

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

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


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