Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Oracle > НЕ DML инструкции в процедурах и функциях


Автор: BIZ0N 8.6.2006, 20:37
Субд Oracle 9i или Oracle 10g XE Release 10.2.0.1.0

Как реализовать нечто подобное вот этому:

Код

-- Декларация пакета
CREATE OR REPLACE PACKAGE my_package IS

   PROCEDURE new_user (uname in sys.dba_users.username%TYPE, upass in sys.dba_users.username%TYPE);
    
END my_package;
/
-- Конец

Код

-- Описание пакета
CREATE OR REPLACE PACKAGE BODY my_package IS

   -- Процедура создания нового пользователя
   PROCEDURE new_user (uname in sys.dba_users.username%TYPE, upass in sys.dba_users.username%TYPE)
   IS
   BEGIN
      
      CREATE USER uname
      IDENTIFIED BY upass
      PROFILE my_profile;

      GRANT "CONNECT" TO uname;
      GRANT EXECUTE ON  "my_sheme"."my_package" TO uname;

   END new_user;
   -- Конец процедуры

END my_package;
/
-- Конец


 smile 

P.S.: Заранее спасибо!!!  

Автор: Sqlninja 8.6.2006, 22:20
Код

   PROCEDURE new_user (
      uname        IN   SYS.dba_users.username%TYPE
    , upass        IN   SYS.dba_users.username%TYPE
    , my_sheme     IN   VARCHAR2
    , my_package   IN   VARCHAR2
   )
   IS
   BEGIN
      EXECUTE IMMEDIATE 'CREATE USER ' || uname || ' IDENTIFIED BY ' || upass || ' PROFILE my_profile';

      EXECUTE IMMEDIATE 'GRANT CONNECT TO ' || uname;

      EXECUTE IMMEDIATE 'GRANT EXECUTE ON ' || my_sheme || '.' || my_package || ' TO ' || uname;
   END new_user;

 

Автор: batigoal 9.6.2006, 08:53
Кстати, а я вроде слышал, что EXECUTE IMMEDIATE не следует злоупотреблять. Из-за чего? Из соображений производительности, или целостности, или еще каких-то?.. 

Автор: Sqlninja 9.6.2006, 10:57
Динамический SQL - это в общем не есть хорошо, но он имеет и свои преймущества. Основные недостатки  - это невозможность проверки на этапе компиляции и, как правило, худшая производительность. Кстати, EXECUTE IMMEDIATE это еще ничего, в ранних версиях был только тормозной пакет DMBS_SQL.
Общее правило таково, что динамический SQL следует использовать лишь тогда когда невозможно обойтись статическим, как например в этом случае. А также:

- при выполнении DDL операторов в PL\SQL
- при ссылках на объекты не существующие на этапе компиляции
- при выполнении динамических запросов или блоков
- при динамических операциях с правами вызывающего

Кажется, все. 

Автор: batigoal 9.6.2006, 11:03
Ясно, спасибо 

Автор: chief39 13.9.2006, 19:39
Осмелюсь поднять старую тему, дабы избежать криков "поиск рулит!!" smile

Возникло подозрение, что DDL через execute immediate нельзя выполнять...

Но раз уж в топике так написано....
Делюсь тем, что есть:

Выполняю из консоли тоада
Код

create user new_user identified by new_user; 

Сервер пишет:
Код

User created.


Всё ок.

Но надо динамически...
И тут валится в самом простом кейсе:
вот так:
Код

execute immediate ' create user new_user identified by new_user; ';

Код

ORA-06550: line 1, column 17:
PLS-00103: Encountered the symbol " create user new_user identified by new_user; " when expecting one of the following:

   := . ( @ % ;
The symbol ":=" was substituted for " create user new_user identified by new_user; " to continue.


вот так:
Код

DBMS_SQL.EXECUTE(' create user new_user identified by new_user; ');

Код

ORA-00900: invalid SQL statement


В том числе и если не писать ";" в самом стринге запроса.

оракл - 10.1.0

Голова не варит совершенно, посему очень полагаюсь на помощь smile)

Автор: LSD 13.9.2006, 20:13
Ты чегой-то перемудрил в процедуре.
Код
create or replace procedure CREATE_USER is
begin
  execute immediate 'create user new_user identified by new_user';
end CREATE_USER;
/

нормально отрабатывает, только не надо забывать про то что привилегию create user надо выдать явно, а не через роль.

Автор: chief39 14.9.2006, 12:18
Цитата(LSD @  13.9.2006,  20:13 Найти цитируемый пост)
Ты чегой-то перемудрил в процедуре.

Это не процедура - это неименованый кусок кода. скриптяра.

Цитата(LSD @  13.9.2006,  20:13 Найти цитируемый пост)
нормально отрабатывает, только не надо забывать про то что привилегию create user надо выдать явно, а не через роль. 

я под sys as sysdba это делаю... просто так создаёт нормально smile

Добавлено @ 12:32 
LSD, если создавать процедурой - отрабатывает....

Блин.. создавать процедуру  для создания юзеров... кампилец....
 smile 

без процедурной оболочки не пашет smile

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

КРИК К ЗВЁЗДАМ: НУ ЧЁ ЗА ХЕРНЯ?!?!?! ( Откуда такая несправедливость?)

Автор: chief39 14.9.2006, 12:52
ЗЫ: не совсем в тему, но...

Инициализация таблиц согласно мануалам должна проходить вот так:

Код

declare
       TYPE mylist IS TABLE OF varchar(20) INDEX BY BINARY_INTEGER;
       modules mylist := mylist('prebillling');
       users mylist;
       
begin

bla-bla...


Но... 
Код


ORA-06550: line 3, column 24:
PLS-00222: no function with name 'MYLIST' exists in this scope
ORA-06550: line 3, column 13:
PL/SQL: Item ignored
ORA-06550: line 62, column 15:
PLS-00320: the declaration of the type of this expression is incomplete or malformed
ORA-06550: line 62, column 3:
PL/SQL: Statement ignored
ORA-06550: line 71, column 17:
PLS-00320: the declaration of the type of this expression is incomplete or malformed
ORA-06550: line 71, column 5:
PL/SQL: Statement ignored


Подумалось - а вдруг фигурные? - но, фик.
Если поэлементно инициализировать потом - один елемент пролеает - при переборе ругается

Добавлено @ 13:06 
В принципе сделал, но вопросы всё равно для меня интересные smile

Да простят меня "оракулы", по после сибейса очччень неудобная штука smile

Автор: LSD 14.9.2006, 13:23
Цитата(chief39 @  14.9.2006,  13:18 Найти цитируемый пост)
Это не процедура - это неименованый кусок кода. скриптяра.

Зачем тебе в скрипте понадобилось execute immediate? Там же и без этого можно выполнять операторы DDL?
Да и как анонимный PL/SQL блок
Код
begin
  execute immediate 'create user new_user identified by new_user';
end CREATE_USER;
/

оно отрабатывает нормально.

Цитата(chief39 @  14.9.2006,  13:52 Найти цитируемый пост)
Инициализация таблиц согласно мануалам должна проходить вот так:
...

Не понял, поподробней в чем проблема?


Цитата(chief39 @  14.9.2006,  13:18 Найти цитируемый пост)
КРИК К ЗВЁЗДАМ: НУ ЧЁ ЗА ХЕРНЯ?!?!?! ( Откуда такая несправедливость?)

Тссс! Не шуми, а то сюда сейчас вся "Фабрика звезд" нагрянет smile

Автор: chief39 14.9.2006, 13:37
Цитата(LSD @  14.9.2006,  13:23 Найти цитируемый пост)
Зачем тебе в скрипте понадобилось execute immediate? Там же и без этого можно выполнять операторы DDL?

Создаётся много схем. Названия формируются динамически.

Цитата(LSD @  14.9.2006,  13:23 Найти цитируемый пост)
Да и как анонимный PL/SQL блок

Цитата(LSD @  14.9.2006,  13:23 Найти цитируемый пост)
оно отрабатывает нормально.

У меня валится smile Как выше описано smile

Цитата(LSD @  14.9.2006,  13:23 Найти цитируемый пост)
Не понял, поподробней в чем проблема?

Ну... в коде есть. Пытаюсь создать и сразу проинициализировать список.
Но валится

Цитата(LSD @  14.9.2006,  13:23 Найти цитируемый пост)
Тссс! Не шуми, а то сюда сейчас вся "Фабрика звезд" нагрянет

Эттто ещё кто??? 

Автор: LSD 14.9.2006, 13:51
Цитата(chief39 @  14.9.2006,  14:37 Найти цитируемый пост)
У меня валится  Как выше описано

Мой тестовый пример, или твой?

Цитата(chief39 @  14.9.2006,  14:37 Найти цитируемый пост)
Ну... в коде есть. Пытаюсь создать и сразу проинициализировать список.

Прям в секции объявления smile 
Так нельзя. В секции объявления, переменные только объявляются, иниализация в блоке кода.


Цитата(chief39 @  14.9.2006,  14:37 Найти цитируемый пост)
Эттто ещё кто???

Страшные люди, умеют своим пением сводить людей с ума: люди начинают биться головой о стену, у них начинаются приступы тошноты и беспричинной агресси.

Автор: chief39 14.9.2006, 14:21
Цитата(LSD @  14.9.2006,  13:51 Найти цитируемый пост)
Мой тестовый пример, или твой?

Блин... если бегин-эндом обрамить - пашет smile

С меня пиво smile)) Белое, ессно  smile 



Цитата(LSD @  14.9.2006,  13:51 Найти цитируемый пост)
Прям в секции объявления smile 
Так нельзя. В секции объявления, переменные только объявляются, иниализация в блоке кода.

А вот  http://www.psoug.org/reference/collections.html говорили что можно smile
Код

 DECLARE

TYPE clientele IS TABLE OF VARCHAR2(64);
group1 clientele := clientele('Customer 1', 'Customer 2');
group2 clientele := clientele('Customer 1', 'Customer 3');

BEGIN

Я и поверил было... smile



Цитата(LSD @  14.9.2006,  13:51 Найти цитируемый пост)
Страшные люди, умеют своим пением сводить людей с ума: люди начинают биться головой о стену, у них начинаются приступы тошноты и беспричинной агресси.

Это из какого-то анека? Или фэнтези? Что за фабрика звёзд?

Автор: LSD 14.9.2006, 14:45
Цитата(chief39 @  14.9.2006,  15:21 Найти цитируемый пост)
А вот  ТУТ говорили что можно

Ээээ, ты туда не читай, ты http://download-uk.oracle.com/docs/cd/B19306_01/appdev.102/b14261/collections.htm#sthref1042 читай, а то савсэм обманут будешь smile

Цитата(chief39 @  14.9.2006,  15:21 Найти цитируемый пост)
С меня пиво )) Белое, ессно

Неа, черное (Гиннес) smile 

Цитата(chief39 @  14.9.2006,  15:21 Найти цитируемый пост)
Это из какого-то анека? Или фэнтези? Что за фабрика звёзд?

Счастливый человек, не знает что такое http://www.1tv.ru/fabrika/ (на МузТВ очень интересный факт показали, рядом с Фабрикой Звезд находится завод по производству слуховых аппаратов smile ).

Автор: chief39 14.9.2006, 15:24
Цитата(LSD @  14.9.2006,  14:45 Найти цитируемый пост)
Неа, черное (Гиннес)

Ок ;) Приезжай smile




Цитата(LSD @  14.9.2006,  14:45 Найти цитируемый пост)
Ээээ, ты туда не читай, ты сюда читай, а то савсэм обманут будешь


Код

declare
       TYPE mylist IS TABLE OF varchar(20) INDEX BY BINARY_INTEGER;
       modules mylist;
       users mylist;
       
begin

     modules := mylist('prebilling','huilling');

blaaaaaaa....


Код

 ORA-06550: line 12, column 14:
PLS-00222: no function with name 'MYLIST' exists in this scope
ORA-06550: line 12, column 3:
PL/SQL: Statement ignored

smile Тэм нэ мэнэе.. smile

Цитата(LSD @  14.9.2006,  14:45 Найти цитируемый пост)
Фабрика звезд 

Мдя smile

Автор: LSD 14.9.2006, 17:08
Цитата(chief39 @  14.9.2006,  16:24 Найти цитируемый пост)
Тэм нэ мэнэе..

Ты сегодня в ударе smile зачем тебе ассоциативный массив понадобился?

Если тебе надо создать ассоциативный массив, то делай это так:
Код
declare
  type MYLIST is table of varchar(20) index by binary_integer;
  MODULES MYLIST;
  USERS MYLIST;
begin
  MODULES(1) := 'prebilling';
  MODULES(55) := 'huilling';
end;
/

Если просто вложеную таблицу:
Код
declare
  type MYLIST is table of varchar(20);
  MODULES MYLIST;
  USERS MYLIST;
begin
  MODULES := MYLIST('prebilling','huilling');
end;
/

Автор: chief39 14.9.2006, 17:52
Цитата(LSD @  14.9.2006,  17:08 Найти цитируемый пост)

Если тебе надо создать ассоциативный массив, то делай это так:

Так и делаю.
Но при переборе от 1 до COUNT на пропущенных элементах ругается smile

Цитата(LSD @  14.9.2006,  17:08 Найти цитируемый пост)

Если просто вложеную таблицу:

Дык я ведь такой же кусок кода привёл вроде.... (хотя в оракле я уже ни в чём не уверен smile )
И он валится как я написал выше  smile 

Автор: LSD 14.9.2006, 18:12
Цитата(chief39 @  14.9.2006,  18:52 Найти цитируемый пост)
Дык я ведь такой же кусок кода привёл вроде....

Нет не такой же, у тебя тип объявлен как ассоциативный массив, а инициализируешь ты его как простую вложенную таблицу.

Цитата(chief39 @  14.9.2006,  18:52 Найти цитируемый пост)
Но при переборе от 1 до COUNT на пропущенных элементах ругается

Завтра гляну (домой пора: сегодня пиво и блюз smile ).

Автор: LSD 15.9.2006, 11:42
Курение мануалов дало следующий результат smile 
Итерацию по ассоциативным массивам надо делать так:
Код
create or replace package NTABLE_TYPE is

  type HASHTABLE_TYPE is table of varchar(20) index by binary_integer;

  procedure ITERATE;

end NTABLE_TYPE;
/

create or replace package body NTABLE_TYPE is

  procedure ITERATE is
    HASHTABLE HASHTABLE_TYPE;
    I         binary_integer;
  begin
    DBMS_OUTPUT.ENABLE;
    DBMS_OUTPUT.PUT_LINE('Zajigaem!');
  
    HASHTABLE(1) := 'one';
    HASHTABLE(2) := 'two';
    HASHTABLE(5) := 'five';
  
    I := HASHTABLE.first;
    loop
      exit when I is null;
      DBMS_OUTPUT.PUT_LINE(TO_CHAR(I) || ' = ' || HASHTABLE(I));
      I := HASHTABLE.next(I);
    end loop;
  end;

end NTABLE_TYPE;
/

Автор: chief39 15.9.2006, 14:30
Цитата(LSD @  15.9.2006,  11:42 Найти цитируемый пост)
Курение мануалов дало следующий результат smile 
Итерацию по ассоциативным массивам надо делать так:

Спасиб smile
Переделаю, как вернусь из Карпат smile))
С меня оба пива smile))

Автор: chief39 15.9.2006, 15:49
Всё. Сделал как таблицу smile
Ну ййяво нафик
Теперь душа чиста.
Спасибки smile

Автор: LSD 15.9.2006, 23:28
Цитата(chief39 @  15.9.2006,  15:30 Найти цитируемый пост)
Переделаю, как вернусь из Карпат ))

Афигеть, он еще в горах катется smile  Учи матчасть! smile

Пожалуйста smile

Автор: chief39 19.9.2006, 11:45
Цитата(LSD @  15.9.2006,  23:28 Найти цитируемый пост)
Афигеть, он еще в горах катется smile  Учи матчасть! smile

Я не катаюсь, я пьянствую. Во флейме написал.
Вот http://forum.vingrad.ru/index.php?act=ST&f=193&t=112531&st=0#entry859202

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)