Модераторы: LSD

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> как запустить хранимую процедуру 
:(
    Опции темы
DEER
Дата 23.3.2006, 15:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 749
Регистрация: 12.4.2005
Где: г. Рязань

Репутация: нет
Всего: 13



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 одна фигня..

Не подскажите в чем проблема?

Это сообщение отредактировал(а) DEER - 23.3.2006, 15:53


--------------------
 
PM MAIL WWW ICQ MSN   Вверх
DEER
Дата 23.3.2006, 16:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 749
Регистрация: 12.4.2005
Где: г. Рязань

Репутация: нет
Всего: 13



попробовал ещё одним способом
Код

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


smile мистика


--------------------
 
PM MAIL WWW ICQ MSN   Вверх
batigoal
Дата 23.3.2006, 17:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Нелетучий Мыш
****


Профиль
Группа: Участник Клуба
Сообщений: 6423
Регистрация: 28.12.2004
Где: Санктъ-Петербургъ

Репутация: 2
Всего: 151



А если без имени схемы попробовать?
Код

BEGIN 
  PC_STAT.calls_time_report;
END;



--------------------
"Чтобы правильно задать вопрос, нужно знать большую часть ответа" (Р. Шекли)
ЖоржЖЖ
PM WWW   Вверх
DEER
Дата 23.3.2006, 17:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 749
Регистрация: 12.4.2005
Где: г. Рязань

Репутация: нет
Всего: 13



тоже самое,
причем пишу PS_STAT. жду секунду повляестся список, в нём ЕСТЬ эта функция......

а может дело в том что это функция а не процедура?


--------------------
 
PM MAIL WWW ICQ MSN   Вверх
LSD
Дата 23.3.2006, 21:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

Репутация: 18
Всего: 538



В 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;



--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
DEER
Дата 24.3.2006, 09:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 749
Регистрация: 12.4.2005
Где: г. Рязань

Репутация: нет
Всего: 13



Спасибо, заработало!!!

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

просто выполняется и всё, т.е. результат не выводится никуда.. smile
а задумка была такая:
мне надо вывести в одном запросе даныые, они берутся из одной таблицы, но два раза т.е. примерно так
Код
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, а как теперь получить из неё значения, как будто это был бы запрос ?? smile


--------------------
 
PM MAIL WWW ICQ MSN   Вверх
LSD
Дата 24.3.2006, 12:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

Репутация: 18
Всего: 538



Результат первого запроса не эквивалентен результатам вторых 2-х. Т.к. первый порождает декартово произведение таблиц, а второй и третий нет.

Так что поподробней: скрипт создания таблицы, текст запроса, и что надо олучить в итоге.


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
DEER
Дата 24.3.2006, 13:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 749
Регистрация: 12.4.2005
Где: г. Рязань

Репутация: нет
Всего: 13



млин комерческая тайна 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 и всё это дело висит.

Нормуль объяснил? smile
Добавлено @ 13:37
тока проблема не в этом.
как функцию написать я уж сооброжу,
мне бы узнать как эту функцию вызвать, чтобы результат её работы был как у запроса,
те пишу что то в SQLEditor'е, запускаю, результат напечан в DataGrid

Это сообщение отредактировал(а) DEER - 27.3.2006, 08:36


--------------------
 
PM MAIL WWW ICQ MSN   Вверх
LSD
Дата 26.3.2006, 13:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

Репутация: 18
Всего: 538



По поводу производительности, не выйдет у тебя сделать объединение быстрее чем это сделает сам 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)
/



--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
DEER
Дата 27.3.2006, 08:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 749
Регистрация: 12.4.2005
Где: г. Рязань

Репутация: нет
Всего: 13



Цитата(LSD @ 26.3.2006, 13:36)
И по поводу запросов те два запроса что ты привел полностью идентичны.


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

проблему решил так.
Уже в програме посылаю два запроса на сервер, и в программе же объединяю результаты запросов. Просто не оставалось ничего другого, надо было сдавать работающий отчет....


--------------------
 
PM MAIL WWW ICQ MSN   Вверх
BIZ0N
  Дата 27.5.2006, 02:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 7
Регистрация: 27.5.2006

Репутация: нет
Всего: нет



Помогите начинающему smile 
проблема похожая. поэтому создавать новую тему не стал.

субд 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  smile 

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

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


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

 smile Замучился уже, помогите плз (хочу знать глючит ли PL*SQL Worksheet и как посмотреть результирующую выборку в PL/SQL Developer) 
PM MAIL   Вверх
batigoal
Дата 27.5.2006, 12:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Нелетучий Мыш
****


Профиль
Группа: Участник Клуба
Сообщений: 6423
Регистрация: 28.12.2004
Где: Санктъ-Петербургъ

Репутация: 2
Всего: 151



Вполне возможно, что причина в слешах ('/'). По крайней мере, в PL/SQL Developer этот код будет корректно выполнен в Command Window и ошибочно - в SQL Window.

Посмотри в PL/SQL Developer'е заголовок пакета rrrac_admin. не исключено, что к нему там прилеплена оставшаяся часть файла. 


--------------------
"Чтобы правильно задать вопрос, нужно знать большую часть ответа" (Р. Шекли)
ЖоржЖЖ
PM WWW   Вверх
BIZ0N
Дата 27.5.2006, 15:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 7
Регистрация: 27.5.2006

Репутация: нет
Всего: нет



не ... в девелопере работаю только в sql window (имею склонность к альтруизму  smile ) и вообще в девелопере показывает что пакет создан нормально!!! вот только у меня никак не получается посмотреть в нем результирующую выборку... (еще не разобрался с интерфейсом, я с ним знаком всего 2 дня)

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

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

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

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

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

P.S.:
ОФФТОП: после выполнения таких пакетных процедур нухно закрывать курсор который они возвращают ? 
PM MAIL   Вверх
batigoal
Дата 27.5.2006, 16:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Нелетучий Мыш
****


Профиль
Группа: Участник Клуба
Сообщений: 6423
Регистрация: 28.12.2004
Где: Санктъ-Петербургъ

Репутация: 2
Всего: 151



Я же сказал, проверь текст пакета в девелопере. У нас бывало такое, что пакет виден, как валидный, а исходник у него неправильный.
И попробуй выполнить тот же скрипт в Command window девелопера. 


--------------------
"Чтобы правильно задать вопрос, нужно знать большую часть ответа" (Р. Шекли)
ЖоржЖЖ
PM WWW   Вверх
Sqlninja
Дата 28.5.2006, 22:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 353
Регистрация: 15.5.2006
Где: San Francisco, CA

Репутация: 13
Всего: 13



1) Не используйте PL*SQL Workshit. 


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


2) только 2 пакета под SYSTEM быть не может. покрутите скроллинг.
 


--------------------
It's better to burn out than to fade away.
PM MAIL WWW ICQ   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Oracle"
Zloxa
LSD

Данный раздел предназначен для обсуждения проблем с Oracle Database, другие продукты Oracle здесь не обсуждаются. Просьба при создании темы, придерживаться следующих правил:

  • при создании темы давайте ей осмысленное название, описывающее суть проблемы
  • указывайте используемую версию базы, способ соединения и язык программирования
  • при ошибках обязательно приводите код ошибки и сообщение сервера
  • приводите код в котором возникла ошибка, по возможности дайте тестовый пример демонстрирующий ошибку
  • при вставке кода используйте соответсвующие теги: [code=sql] [/code] для подсветки SQL и PL/SQL кода, [code=java] [/code] - для Java, и т.д.

  • документация по Oracle: 9i, 10g, 11g
  • книги по Oracle можно поискать здесь
  • действия модераторов можно обсудить здесь

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Zloxa, LSD.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Oracle | Следующая тема »


 




[ Время генерации скрипта: 0.1209 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.