как запустить хранимую процедуру

 
0
 
Oracle
ava
DEER | 23.03.2006, 15:51
Oracle 8
среда TOAD

Пусть есть пакет с подпрограммами PC_STAT

хочу добавить в него ещё одну функцию, которая должна возвращать набор данных(таблица, в которой поля буду в функции подсчитывать)
в SPEC пишу

CREATE OR REPLACE package pc_stat is

TYPE time_calls_record IS RECORD ( -- тип записи таблцы результата
provider_name varchar2(50),
incoming_duration NUMBER(7),
outcoming_duration NUMBER(7));
TYPE time_calls_list IS TABLE OF time_calls_record; -- тип - таблица результата

function calls_time_report return time_calls_list; -- сама функция
end pc_stat;
/


в BODY пишу

CREATE OR REPLACE package body pc_stat is

function calls_time_report return time_calls_list is
list_result time_calls_list;
rec time_calls_record;
begin
rec.provider_name := 'ПРЕВЕД';
rec.incoming_duration := 123;
rec.outcoming_duration := 321;

list_result(0) := rec;

return list_result;
end;

end pc_stat;
/


компилирую сначала SPEC потом BODY
все проходит без ошибок...
как мне теперь запустить её и посмотреть результат?
Если пишу в SQL Editor'е запрос
BEGIN qqq.PC_STAT.calls_time_report ; END;

qqq - схема

Oracl выдаёт ошибку:
Цитата
ORA-06550: Строка 2, столбец 7:

PLS-00221: 'CALLS_TIME_REPORT' не является процедурой или не определена

ORA-06550: Строка 2, столбец 7:

PL/SQL: Statement ignored


Если пишу такой запрос
qqq.PC_STAT.calls_time_report

то
Цитата
ORA-00900: неверно предложение на языке SQL


запускать пытаюсь и как Excecute Statement и как Excecute Script одна фигня..

Не подскажите в чем проблема?
Comments (19)
ava
DEER | 23.03.2006, 16:31 #
попробовал ещё одним способом

SELECT qqq.PC_STAT.calls_time_report FROM dual

говорит
Цитата
ORA-06550: Строка 1, столбец 7:

PLS-00221: 'CALLS_TIME_REPORT' не является процедурой или не определена

ORA-06550: Строка 1, столбец 7:

PL/SQL: Statement ignored



SELECT qqq.PC_STAT.calls_time_report FROM dual


:( мистика
ava
batigoal | 23.03.2006, 17:13 #
А если без имени схемы попробовать?

BEGIN
PC_STAT.calls_time_report;
END;
ava
DEER | 23.03.2006, 17:26 #
тоже самое,
причем пишу PS_STAT. жду секунду повляестся список, в нём ЕСТЬ эта функция......

а может дело в том что это функция а не процедура?
ava
LSD | 23.03.2006, 21:57 #
В PL/SQL нельзя игнорировать возвращаемое значение. Кошерный способ такой:
declare
VAL PC_STAT.TIME_CALLS_LIST;
begin
VAL := LSD.PC_STAT.CALLS_TIME_REPORT;
end;
/


И еще у тебя ошибка в функции, надо так:
  function CALLS_TIME_REPORT return TIME_CALLS_LIST is
LIST_RESULT TIME_CALLS_LIST;
REC TIME_CALLS_RECORD;
begin
REC.PROVIDER_NAME := 'ÏÐÅÂÅÄ';
REC.INCOMING_DURATION := 123;
REC.OUTCOMING_DURATION := 321;
LIST_RESULT := TIME_CALLS_LIST(REC);
return LIST_RESULT;
end;
ava
DEER | 24.03.2006, 09:30 #
Спасибо, заработало!!!

Только теперь блок
declare    
VAL PC_STAT.TIME_CALLS_LIST;
begin
VAL := LSD.PC_STAT.CALLS_TIME_REPORT;
end;
/

просто выполняется и всё, т.е. результат не выводится никуда.. :(
а задумка была такая:
мне надо вывести в одном запросе даныые, они берутся из одной таблицы, но два раза т.е. примерно так
SELECT t.NAME, SUM(a.duration), SUM(b.duration)
FROM table t, data a, data b
WHERE (t.id = a.table_id)
AND (t.id = b.table_id)
GROUP BY t.NAME


этот запрос подвисает часа на три.
если же выпонить два запроса
SELECT t.NAME, SUM(a.duration)
FROM table t, data a
WHERE (t.id = a.table_id)
GROUP BY t.NAME

и
SELECT t.NAME, SUM(b.duration)
FROM table t, data b
WHERE (t.id = b.table_id)
GROUP BY t.NAME

то каждый по отдельности выполняется за 5 минут т.е. оба за 10 минут.
Логично было бы написать ф-ю, которая всё это дело считала бы за два захода, потом соединяла бы их в одну таблицу и печатала результат.

Функцию запускаьб я научился при помощи LSD, а как теперь получить из неё значения, как будто это был бы запрос ?? :qstn
ava
LSD | 24.03.2006, 12:48 #
Результат первого запроса не эквивалентен результатам вторых 2-х. Т.к. первый порождает декартово произведение таблиц, а второй и третий нет.

Так что поподробней: скрипт создания таблицы, текст запроса, и что надо олучить в итоге.
ava
DEER | 24.03.2006, 13:22 #
млин комерческая тайна smile .
короче есть список операторов
CREATE TABLE PROVIDERS
(
PR_ID NUMBER(2) NOT NULL,
PR_NAME VARCHAR2(50) NOT NULL,
PR_SHORT_NAME VARCHAR2(20)
)

каждому оператору соответствует свой диапазон номеров
CREATE TABLE PROVIDERS_RANGE
(
PR_ID NUMBER,
PR_PVIDER_ID NUMBER,
PR_FROM_NUMER VARCHAR2(6),
PR_TO_NUMER VARCHAR2(6)
)

в БД пишутся звонки (как они пишутся не важно, и вся структура таблицы куда пишутся тоже smile )
CREATE TABLE AMA_IACHASTA
(
RECORD_OWNER VARCHAR2(31), --номнер с которого звонили
DT DATE, --врем звонка
DURATION NUMBER(20), -- продолжительность звонка
PARTNER_DN VARCHAR2(31), --номер на который звонили
)

нужно получить список где будет
- оператор,
- продолжительность входящих звонков,
- продолжительность исходящих звонков.
запрос написал такой
для исходящих звонков
SELECT prov.PR_ID, prov.PR_NAME, SUM(ai.DURATION) durat
FROM AMA_IACHASTA ai, PROVIDERS prov, PROVIDERS_RANGE pr
WHERE
(ai.DT >= to_date ('01.01.2006', 'dd.mm.yyyy hh:mi'))
AND (ai.DT < to_date ('01.02.2006', 'dd.mm.yyyy hh:mi'))
AND (pr.PR_PVIDER_ID = prov.PR_ID)
AND (ai.PARTNER_DN >= pr.PR_FROM_NUMER)
AND (ai.PARTNER_DN <= pr.PR_TO_NUMER)
GROUP BY prov.PR_ID, prov.PR_NAME

для входящих звонков
SELECT prov.PR_ID, prov.PR_NAME, SUM(ai.DURATION) durat
FROM AMA_IACHASTA ai, PROVIDERS prov, PROVIDERS_RANGE pr
WHERE
(ai.DT >= to_date ('01.01.2006', 'dd.mm.yyyy hh:mi'))
AND (ai.DT < to_date ('01.02.2006', 'dd.mm.yyyy hh:mi'))
AND (pr.PR_PVIDER_ID = prov.PR_ID)
AND (ai.RECORD_OWNER >= pr.PR_FROM_NUMER)
AND (ai.RECORD_OWNER <= pr.PR_TO_NUMER)
GROUP BY prov.PR_ID, prov.PR_NAME

теперь это дело хочется в функции объеденить и вывести в DataGrid Toad'а
записей там видимо - невидимо smile и всё это дело висит.

Нормуль объяснил? ;-)
added later:
тока проблема не в этом.
как функцию написать я уж сооброжу,
мне бы узнать как эту функцию вызвать, чтобы результат её работы был как у запроса,
те пишу что то в SQLEditor'е, запускаю, результат напечан в DataGrid
ava
LSD | 26.03.2006, 13:36 #
По поводу производительности, не выйдет у тебя сделать объединение быстрее чем это сделает сам Oracle. Лучше всего просто попробовать оптимизировать запрос: построить индексы если это уже не сделано, декартово произведение заменить на join и т.п. И по поводу запросов те два запроса что ты привел полностью идентичны.

А получить коллекцию в виде курсора можно так:
create or replace type NUM_ARR as table of number;
/

create or replace function GET_NUM_ARR return NUM_ARR is
RES NUM_ARR;
begin
RES := NUM_ARR();
for I in 1 .. 10 loop
RES.extend;
RES(I) := I;
end loop;
return RES;
end GET_NUM_ARR;
/

select * from table(GET_NUM_ARR)
/
ava
DEER | 27.03.2006, 08:41 #
Цитата (LSD @ 26.3.2006, 13:36)
И по поводу запросов те два запроса что ты привел полностью идентичны.




Упс. ошипка вышла smile исправил

проблему решил так.
Уже в програме посылаю два запроса на сервер, и в программе же объединяю результаты запросов. Просто не оставалось ничего другого, надо было сдавать работающий отчет....
ava
BIZ0N | 27.05.2006, 02:12 #
Помогите начинающему :rolleyes
проблема похожая. поэтому создавать новую тему не стал.

субд Oracle 9i HOME
использую PL*SQL Worksheet
+ пытаюсь освоить PL/SQL Developer


-- Декларация пакета функций администрирования
CREATE OR REPLACE PACKAGE rrrac_admin IS

TYPE ref_cursor IS REF CURSOR;

FUNCTION ls_users RETURN ref_cursor;

END rrrac_admin;
/
-- Конец

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

-- Функция выборки пользователей подсистемы
FUNCTION ls_users RETURN ref_cursor
IS
ls_cursor ref_cursor;
BEGIN

OPEN ls_cursor FOR
SELECT username FROM dba_users
WHERE PROFILE='RRRAC_USER';
RETURN ls_cursor;

END ls_users;
-- Конец функции

END rrrac_admin;
/
-- Конец


В PL/SQL Developer обьект создается без ошибок, а вот в PL*SQL Worksheet кричит, что тело создано с ошибками компиляци... да и вообще последний глючит, по запросу:


SELECT OBJECT_NAME, OBJECT_TYPE, STATUS
FROM USER_OBJECTS
WHERE OBJECT_TYPE = 'PACKAGE BODY'


PL/SQL Developer выдает более сотни пакетов, и среди них rrrac_admin со статусом VALID,
а вот PL*SQL Worksheet находит только 2 обьекта, при этом rrrac_admin имеет статус INVALID :stena

Кроме того, не могу проверить работу функции в PL/SQL Developer :stena
использую конструкцию вида (пишу по памяти, комп с инетом и комп с Oracle находяться далеко друг от друга :( ):

DECLARE
result refcursor;
BEGIN
exec :result := rrrac_admin.ls_users;
print result;
END;


PL/SQL Developer вываливает снизу список переменных (а именно result)? а вот выборки там не видно ... видимо всетаки глючит не PL*SQL, а PL/SQL Developer

:qstn Замучился уже, помогите плз (хочу знать глючит ли PL*SQL Worksheet и как посмотреть результирующую выборку в PL/SQL Developer)
ava
batigoal | 27.05.2006, 12:28 #
Вполне возможно, что причина в слешах ('/'). По крайней мере, в PL/SQL Developer этот код будет корректно выполнен в Command Window и ошибочно - в SQL Window.

Посмотри в PL/SQL Developer'е заголовок пакета rrrac_admin. не исключено, что к нему там прилеплена оставшаяся часть файла.
ava
BIZ0N | 27.05.2006, 15:22 #
не ... в девелопере работаю только в sql window (имею склонность к альтруизму smile ) и вообще в девелопере показывает что пакет создан нормально!!! вот только у меня никак не получается посмотреть в нем результирующую выборку... (еще не разобрался с интерфейсом, я с ним знаком всего 2 дня)

а вот в родном для оракла pl*sql у меня выполнить этот код не получается ... и вообще в отличии от девелопера он показывает что тело пакета - "INVALID" :omg

почему такая разница ? и там и там работаю из под пользователя system...

почему один инструмент по запросу:

SELECT OBJECT_NAME, OBJECT_TYPE, STATUS
FROM USER_OBJECTS
WHERE OBJECT_TYPE = 'PACKAGE BODY'

мне выберает 2 пакета, а другой около сотни (на глаз прикинул smile ) ?

P.S.:
ОФФТОП: после выполнения таких пакетных процедур нухно закрывать курсор который они возвращают ?
ava
batigoal | 27.05.2006, 16:15 #
Я же сказал, проверь текст пакета в девелопере. У нас бывало такое, что пакет виден, как валидный, а исходник у него неправильный.
И попробуй выполнить тот же скрипт в Command window девелопера.
ava
Sqlninja | 28.05.2006, 22:19 #
1) Не используйте PL*SQL Workshit.


Цитата (BIZ0N @ 27.5.2006, 15:22 findReferencedText)
мне выберает 2 пакета, а другой около сотни


2) только 2 пакета под SYSTEM быть не может. покрутите скроллинг.
ava
batigoal | 28.05.2006, 22:46 #
Цитата (Sqlninja @ 28.5.2006, 23:19 findReferencedText)
Не используйте PL*SQL Workshit.

Почему? Мы вполне успешно с ним работаем.
ava
Sqlninja | 28.05.2006, 23:32 #
Цитата (Lamer George @ 28.5.2006, 22:46 findReferencedText)
Почему? Мы вполне успешно с ним работаем.



Эээ.. не знаю. Обьективных причин нет. Но мне не нравится. smile Конечно, можно успешно и в SQL Plus работать, если возможности устраивают. Но это уже скорее топ для "Средства разработки для Oracle".
ava
BIZ0N | 29.05.2006, 00:59 #
Покопался в настройках девелопера, разобрался с интерфесом и с тем что значит входить с правами SYSDBA/SYSOPER/NORMAL...
Заработало !!!

Основная проблема была в том, что пользователь SYSTEM получает права на обьекты в схеме SYS через роль DBA. А так как такая проверка прав (при работе с обьектами) в оракле пока не реализована, то он просто не видел представление DBA_USERS.

Я до сих пор в шоке от того, что в оракле, пользователь SYSTEM, вошедший с правами SYSDBA, может не получить доступ к чему-либо... мда... ребятам из Oracle corp. нужно жить проще!!!

Цитата (Sqlninja @ 28.5.2006, 22:19 findReferencedText)
2) только 2 пакета под SYSTEM быть не может. покрутите скроллинг.


Из вышесказанного обсолютно очевидно, что все обьекты лежат в схеме SYS, а запрос почему-то выгребал их только из локальной схемы ...

А на счет скрола вы меня прямо-таки обидели :( хоть я с ораклом и знаком всего две недели, но я работаю сисадмином уже 3 года и имею диплом IT-инженера... (соответсвенно с базами приходилось иметь дело: mssql, mysql, cashe, куча настольных + postgres - вот база, которая оставляет от работы с ней в основном хорошее впечатление!!! а с оркалом ребята разработчики перемудрили :exclamation )
ava
batigoal | 29.05.2006, 08:10 #
Цитата (BIZ0N @ 29.5.2006, 01:59 findReferencedText)
а с оркалом ребята разработчики перемудрили

Серьезные системы требуют серьезных усилий при изучении, от этого никуда не деться.
ava
Sqlninja | 29.05.2006, 10:26 #
Цитата (BIZ0N @ 29.5.2006, 00:59 findReferencedText)
А на счет скрола вы меня прямо-таки обидели

Ни в коем случае не хотел Вас обидеть. Я работаю с Oracle 5 лет, и иногда совершаю совершенно идиотские ошибки.


Цитата (BIZ0N @ 29.5.2006, 00:59 findReferencedText)
с базами приходилось иметь дело: mssql, mysql, cashe, куча настольных + postgres


Это все системы другого масштаба, даже Cache по мощности не дотягивает. Конечно, поначалу Вам все покажется намного сложнее чем Вы привыкли. Но когда работаешь с терабайтными базами в сотни миллионов записей, где хранится коммерческая информация, к которой нужно как то дать доступ сотням пользователей, становится ясно, ничего ребята не перемудрили а нашли единственно верное решение. ;-)
Please register or login to write.
Firm of day
Вы также можете добавить свою фирму в каталог IT-фирм, и публиковать статьи, новости, вакансии и другую информацию от имени фирмы.
Подробнее
Contributors
ava  LSD   batigoal   DEER   Sqlninja   BIZ0N
advanced
Submit