Вывод из процедуры результатов через OUT параметр
Необходимо реализовать вывод из процедуры через параметр OUT не используя буфера обмена, то есть dbms_output.put_line . Процедура находится в пакете.
PROCEDURE array_app (street IN Streets.TITLE%TYPE, dom IN APARTMENTS.HOUSE%TYPE, res OUT Varchar2) IS CURSOR my_cur IS SELECT DISTINCT idapart FROM POSSESSION; CURSOR cur1 (street IN VARCHAR2, dom IN INTEGER) IS SELECT APARTMENTS.id, num FROM APARTMENTS, Streets WHERE HOUSE = dom AND TITLE = street AND APARTMENTS.IDSTREET = Streets.ID; kv INTEGER; cnumber number; str Varchar2(100); BEGIN res := ''; OPEN cur1 (street, dom); FETCH cur1 INTO cnumber, kv; FOR f IN my_cur LOOP IF f.idapart = cnumber THEN str := res; select str || ', ' || kv INTO res from dual; RETURN; END IF; END LOOP; CLOSE cur1; END;
И вызов процедуры
DECLARE res1 Varchar2(100); BEGIN pack.array_app('Татищева', 75, res1); END;
Пример данных: Это таблица помещений, где соответственно столбцы код, улица и номер дома и номер квартиры:
CREATE TABLE Apartments (id INTEGER PRIMARY KEY, idstreet VARCHAR2(100), house INTEGER NOT NULL, num INTEGER); INSERT INTO Apartments (id, idstreet, house, num) VALUES (1, 'Татищева', 75, 5); INSERT INTO Apartments (id, idstreet, house, num) VALUES (2, 'Кирова', 3, 15); INSERT INTO Apartments (id, idstreet, house, num) VALUES (3, 'Новая', 28, 34); INSERT INTO Apartments (id, idstreet, house, num) VALUES (4, 'Татищева', 75, 150);
Также имеется таблица владения, в которой содержится как раз код объекта владения:
CREATE TABLE Possession (id INTEGER PRIMARY KEY, idapart INTEGER NOT NULL REFERENCES Apartments); INSERT INTO Possession (id, idapart) VALUES (1, 1); INSERT INTO Possession (id, idapart) VALUES (2, 4);
Соответственно, в результате выбирается запись с кодом 1 и возвращается номер квартиры. Если в наборе входных данных будет несколько элементов входящих в обе таблицы с данными, то вернуться должны все соответствующие номера квартир.
Получить текст функции/процедуры из пакета — Oracle
Добрый день.
Появилась задача найти в указанном пакете текст хранимой процедуры или функции.
Получилось только такое:
1 2 3 4 5
SELECT * FROM user_source a WHERE a.type = 'PACKAGE BODY' AND a.name = 'AGENT_SUPPORT' ORDER BY line ASC;
Понимаю что нужно парсить и даже алгоритм некий продумал, но все же решил спросить у вас уважаемые форумчане,
можно ли select’om достать текст из пакета. Может у кого завалялось решение, буду очень благодарен.
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
Ответы с готовыми решениями:
Получить из Oracle в Access результат выполнения процедуры
Добрый день всем! В книге вычитал, что запросы напрямую к серверу в Access (dbSQLPassThrough).
Получить текст процедуры
Здравствуйте, подскажите способы получения текста процедуры, триггера и т.п. Мне нужно реализовать.
Текст,строки,слова процедуры и функции
Вариант 9. 1. Вводится строка произвольного текста. Определить, в каком слове больше букв — в.
Ошибка при компиляции Java-пакета в Oracle
Компилю JAVA sourсe в базе данных Oracle. В коде имеются следующие строки: java.io.File f =.
475 / 238 / 114
Регистрация: 12.05.2016
Сообщений: 647
Нет простого способа без разбора исходника достать текст одной процедуры пакета.
Но вам могут помочь еще вьюхи user_procedures — содержит список всех методов пакетов и user_arguments — содержит параметры всех методов всех пакетов.
Регистрация: 28.04.2012
Сообщений: 117
Сообщение от Anvano 
Нет простого способа без разбора исходника достать текст одной процедуры пакета.
Так и думал, грустно(
может у кого есть готовое решение?
4214 / 3054 / 582
Регистрация: 21.01.2011
Сообщений: 13,205
![]()
Сообщение от Tantay
может у кого есть готовое решение?
Обычно люди работают с текстами процедур через какое-то ГУИ, тот же SQL Developer, доставать текст программным путем — редкая задача.
28 / 28 / 23
Регистрация: 06.10.2016
Сообщений: 74
если у вас есть точное расположение процедуры в пакете то так(например с 50 по 500 строку):
SELECT * FROM user_source WHERE name = 'MYPACK' AND TYPE = 'PACKAGE BODY' AND line BETWEEN 50 AND 500;
опубликованные процедурой точки входа можно получить тут:
SELECT * FROM user_procedures; SELECT * FROM user_arguments;
Регистрация: 28.04.2012
Сообщений: 117
Есть проект в котором под сотню пакетов и под 10 тыс процедур/функций, вся логика находится в них.
Обновление проекта в основном заключается в исправлении этих процедур/функций. Проект для разных пользователей сильно ветвится, поэтому нельзя взять весь пакет и заменить его у пользователя. И возникла такая идея, что бы можно было вытащить нужные процедуры/функции и вставить их у пользователя. Без использования SQL Developer’a
Как вывести код процедуры oracle sql
Мы с вами уже многое знаем о процедурах и функциях, вот теперь давайте поговорим о том, где находятся и хранятся откомпилированные процедуры и функции. После того, как команда CREATE OR REPLACE создает процедуру или функцию, она сразу сохраняется в БД, в скомпилированной форме, которая называется p-кодом (p-code). В p-коде содержатся все обработанные ссылки подпрограммы, а исходный текст преобразован, в вид удобный для чтения системой поддержки PL/SQL. При вызове хранимой процедуры p-код считывается с диска и выполняется. Собственно сам P-код аналогичен объектному коду генерируемому компиляторами языков программирования высокого уровня. В P-коде содержатся обработанные ссылки на объекты (это свойство ранней привязки переменных, о которой мы говорили с вами ранее) по этому выполнение P-кода является сравнительно не дорогой (нересурсоемкой) операцией. Да к слову напомню, что удалить код процедуры или функции из вашей БД (схемы) можно применив, оператор DROP — вот таким образом (в шаге 87 мы уже это делали):
---- DROP PROCEDURE имя_процедуры ------------------------ ---- DROP FUNCTION имя_функции ---------------------------
Теперь давайте вспомним каким образом можно получить информацию о наличии процедур и их работоспособности. Самое простое это выполнить такой запрос к системному представлению USER_OBJECTS вот так:
SELECT OBJECT_NAME, OBJECT_TYPE, STATUS FROM USER_OBJECTS /
В моем случае получилось следующее:
SQL> SELECT OBJECT_NAME, OBJECT_TYPE, STATUS 2 FROM USER_OBJECTS 3 / OBJECT_NAME OBJECT_TYPE STATUS ---------------- ------------------ ------- BOOL_TO_CHAR FUNCTION VALID BOOL_TO_CHARTWO FUNCTION VALID BOYS TABLE VALID CUSTOMERS TABLE VALID FACTORIAL FUNCTION VALID GIRLS TABLE VALID OFFICES TABLE VALID ORDERS TABLE VALID PRODUCTS TABLE VALID PTEST PROCEDURE VALID SALESREPS TABLE VALID SYS_C003505 INDEX VALID SYS_C003506 INDEX VALID SYS_C003507 INDEX VALID SYS_C003511 INDEX VALID SYS_C003512 INDEX VALID SYS_C003513 INDEX VALID SYS_C003515 INDEX VALID TESTINOUT PROCEDURE VALID TESTOUT PROCEDURE VALID OBJECT_NAME OBJECT_TYPE STATUS ---------------- ------------------ ------- TESTPRG PROCEDURE VALID TESTPRGTWO PROCEDURE VALID TESTPRM PROCEDURE VALID TEST_POZ PROCEDURE VALID 24 строк выбрано.
Я включил только три столбца представления, которые дают основную информацию, но если хотите можете использовать все столбцы. Хорошо видно, что у нас с вами все объекты имеют статус VALID, то есть исправны. А, вот как, например увидеть текст хранимой процедуры или функции, для этого используйте системное представление USER_SOURCE. Давайте к примеру выведем текст функции из прошлого шага — FACTORIAL:
SELECT * FROM USER_SOURCE WHERE NAME = 'FACTORIAL' /
SQL> SELECT * FROM USER_SOURCE 2 WHERE NAME = 'FACTORIAL' 3 / NAME TYPE LINE TEXT ---------- ---------- ---------------------------------------------------- FACTORIAL FUNCTION 1 FUNCTION FACTORIAL(NUM IN NUMBER) RETURN NUMBER FACTORIAL FUNCTION 2 IS FACTORIAL FUNCTION 3 FACTORIAL FUNCTION 4 BEGIN FACTORIAL FUNCTION 5 FACTORIAL FUNCTION 6 IF (NUM <=1) THEN FACTORIAL FUNCTION 7 RETURN (NUM); FACTORIAL FUNCTION 8 ELSE FACTORIAL FUNCTION 9 RETURN (NUM * FACTORIAL(NUM-1)); FACTORIAL FUNCTION 10 FACTORIAL FUNCTION 11 END IF; FACTORIAL FUNCTION 12 FACTORIAL FUNCTION 13 END FACTORIAL; 13 строк выбрано.
Вот и содержимое самой функции! Все можно найти в системных представлениях. А, что если при создании функции или процедуры происходит ошибка компиляции? Давайте рассмотрим такой вариант. Создадим процедуру намеренно с ошибкой:
CREATE OR REPLACE PROCEDURE TESTERR(NUM IN NUMBER) IS K NUMBER; BEGIN K := NUM END TESTERR; /
SQL> CREATE OR REPLACE PROCEDURE TESTERR(NUM IN NUMBER) 2 IS 3 4 K NUMBER; 5 6 BEGIN 7 8 K := NUM 9 10 END TESTERR; 11 / Предупреждение: Процедура создана с ошибками компиляции.
Правильно, в данном случае мы забыли поставить ";" после завершения строки K := NUM. Вот теперь давайте дадим такой запрос:
SELECT OBJECT_NAME, OBJECT_TYPE, STATUS FROM USER_OBJECTS WHERE STATUS = 'INVALID' /
SQL> SELECT OBJECT_NAME, OBJECT_TYPE, STATUS 2 FROM USER_OBJECTS 3 WHERE STATUS = 'INVALID' 4 / OBJECT_NAME OBJECT_TYPE STATUS -------------------------- ------------------ ------- TESTERR PROCEDURE INVALID
Странно, процедура вроде бы создана, ее p-код присутствует, но она не исправна! Попробуем вызвать ее:
EXEC TESTERR;
Ответ будет таким:
SQL> EXEC TESTERR; BEGIN TESTERR; END; * ошибка в строке 1: ORA-06550: Строка 1, столбец 7: PLS-00905: неприемлемый объект MILLER.TESTERR ORA-06550: Строка 1, столбец 7: PL/SQL: Statement ignored
Все верно - процедура с ошибками! Так вот, я морочил вам голову, только по тому, чтобы вы ясно представляли себе куда бежать, если что-то не выходит! А вот теперь повторим компиляцию:
. . 7 8 K := NUM 9 10 END TESTERR; 11 / Предупреждение: Процедура создана с ошибками компиляции.
И дадим такую строку:
SHOW ERRORS
SQL> SHOW ERRORS Ошибки для PROCEDURE TESTERR: LINE/COL ERROR -------- ----------------------------------------------------------------- 10/1 PLS-00103: Встретился символ "END" в то время как ожидалось одно из следующих: . ( * @ % & = - + ; < / >at in is mod not rem <> or != or ~= >= and or like between || Символ ";" заменен на "END", чтобы можно было продолжать.
Вот теперь кое, кое что стало яснее. Ошибка PLS-00103 означает наличие незавершенного оператора, команда SHOW ERRORS, считывает данные из системного представления USER_ERRORS, вот его описание:
SQL> DESC USER_ERRORS Имя Пусто? Тип --------- -------- ---------------------------- NAME NOT NULL VARCHAR2(30) TYPE VARCHAR2(12) SEQUENCE NOT NULL NUMBER LINE NOT NULL NUMBER POSITION NOT NULL NUMBER TEXT NOT NULL VARCHAR2(4000)
Теперь давайте дадим вот такой запрос:
SELECT NAME, TEXT FROM USER_ERRORS /
Вот и содержимое:
SQL> SELECT NAME, TEXT FROM USER_ERRORS 2 / NAME TEXT ------- --------------------------------------------------------------------------- TESTERR PLS-00103: Встретился символ "END" в то время как ожидалось одно из следующих: . ( * @ % & = - + ; < / >at in is mod not rem <> or != or ~= >= and or like between || Символ ";" заменен на "END", чтобы можно было продолжать.
Вообще это дело вкуса, но лучше использовать SHOW ERRORS - так удобнее. И будет ясно видно где ошибка! Давайте удалим нашу "инвалидную" процедуру и вы сможете сами поработать над тем, что я вам излагал! Итак:
DROP PROCEDURE TESTERR / SQL> DROP PROCEDURE TESTERR 2 / Процедура удалена.
Пока все, поработайте сами! 🙂
Как вывести код процедуры oracle sql
Собственно, сабж. Хотелось бы получить результат в том виде, в котором его умеет возвращать PL/SQL developer. Про существование пакета DBMS_METADATA осведомлен, но документация по нему, во-первых, тяжеловата, а во-вторых, он корежит исходный текст (приписывает префикс схемы и кавычки)
Re: Как получить текст хранимой процедуры (Oracle)?
| От: | wildwind | |
| Дата: | 28.02.07 23:50 | |
| Оценка: | 3 (1) | |
Здравствуйте, Lombrozo, Вы писали:
L>Собственно, сабж. Хотелось бы получить результат в том виде, в котором его умеет возвращать PL/SQL developer. Про существование пакета DBMS_METADATA осведомлен, но документация по нему, во-первых, тяжеловата, а во-вторых, он корежит исходный текст (приписывает префикс схемы и кавычки)
См. USER_SOURCE.
Но разбираться с ним вряд ли будет проще, чем select dbms_metadata.get_ddl('PROCEDURE', 'MY_PROC') from dual. А кавычками он не корежит текст, а наоборот, защищает его от искажений.
Re: Как получить текст хранимой процедуры (Oracle)?
| От: | Пингвиненок |
| Дата: | 01.03.07 09:19 |
| Оценка: |
Здравствуйте, Lombrozo, Вы писали:
SELECT text FROM all_source WHERE TYPE = UPPER ('procedure') AND NAME = UPPER ('VALIDATE_CONTEXT') ORDER BY line;
То что меня не убивает, делает меня умнее.
Re[2]: Как получить текст хранимой процедуры (Oracle)?
| От: | Пингвиненок |
| Дата: | 01.03.07 09:23 |
| Оценка: |
Здравствуйте, Пингвиненок, Вы писали:
Для SQL Navigator'a
SELECT SUBSTR (text, 1, LENGTH (text) - 1 ) AS source_text FROM all_source WHERE TYPE = UPPER ('procedure') AND NAME = UPPER ('VALIDATE_CONTEXT') ORDER BY line;
