Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Oracle Новый топик    Ответить
 Проблема с функциями pl/sql.  [new]
Andrewshkovskii
Member

Откуда:
Сообщений: 40
Такие дела, сел осваивать Pl/sql, есть задание :
1. Написать функцию, которая для сообщённого ей в качестве входного параметра ID_предмета расчитывает и возвращает баланс на указанную дату (также входной параметр), который складывается из общего дохода по аренде минус начальная стоимость умноженную на количество и минус стоимость ремонта.
Выдать результат работы функции по всей таблице Предметы.

2. Написать триггер автоматически устанавливающий уникальное значение ключа ID_предмета при вставке в таблицу Предметы, в случае если значение явно не указано.
Использовать созданную в общей части работы (пункт 3) последовательность (sequence

Таблицы вот так я создал :
Create TABLE Item

 (ID_Item INTEGER PRIMARY KEY,--Id_предмета

  IName VARCHAR(20) NOT NULL,--название предмета

  Descr VARCHAR(20),--описание

  P_Date DATE NOT NULL,--Дата ппокупки

  E_Date DATE NULL ,--дата списание

  Price FLOAT NOT NULL CHECK(Price>0),--цена

  Amt INTEGER DEFAULT 1 NOT NULL ,

  CHECK(Amt>1),

  CHECK(E_Date>P_Date Or E_Date is NULL)

  );

  commit;

Create TABLE Rent

( ID_Item INTEGER REFERENCES Item(Id_Item),

  Renter Varchar(50),--fhtylfnjh

  S_Date DATE,--дата начала

  E_Date DATE NULL,--дата окончания

  Price FLOAT NOT NULL CHECK(price>0),--стоимость

  Check(E_date is NULL or E_date>S_Date),

  Primary KEY(Renter,S_Date,ID_Item)

  );

  commit;

Create TABLE Repair

( ID_Item INTEGER REFERENCES ITEM ON DELETE CASCADE,

  S_Date DATE,--дата начала

  E_Date DATE NULL,--дата окончания

  Price FLOAT NOT NULL CHECK(Price>0),--стоимость

  Descr VARCHAR2(200),--описание

  CHECK(E_DATE > S_DATE or E_DATE is NULL),

  Primary Key(ID_Item,S_Date)

  );

Последовательность :
Create Sequence UNIQE_ID
 Start with 1000
 Increment by 1;
Теперь проблема вот с этой функцией :
create or replace function GetBalance
(IN_ItemID Item.ID_Item%TYPE, IN_Date Item.E_DATE%TYPE) 
RETURN FLOAT IS
  l_Result   FLOAT;--расчитанный баланс
  l_sum_rent FLOAT;--сумма по ренте
  l_sum_item FLOAT;--сумма по предмету, исп. в формуле
  l_sum_rep  FLOAT;--сумма по ремонту
  l_no_item_found EXCEPTION;--искл. для не найденного предмета
begin
       
  SELECT (item.price * item.amt)
  INTO l_sum_item
         FROM item
         WHERE item.id_item=IN_ItemID;
         
       IF sql%notFound THEN --если ничего не выбранно..
          dbms_output.put_line('No such item');
       END IF;
       
  SELECT SUM(rent.price) 
  INTO l_sum_rent
       FROM Rent
       WHERE rent.id_item = IN_ItemID
       and IN_Date BETWEEN rent.s_date and rent.e_date;
                    
   SELECT SUM(repair.price)
   INTO l_sum_rep
        FROM repair
        WHERE repair.id_item=IN_ItemID
        and IN_Date BETWEEN repair.s_date AND repair.e_date;
        
  l_Result:=l_sum_rent-(l_sum_item - l_sum_rep);         
  return l_Result;
end GetBalance;

Возврашает 12к стоблцов. Данные могу предоставить, но я их импортил из базы акцесса.
Что тут может быть не так?
И насчет 2го задания, где триггер.. Как мне узнать, что не было введено значение для первичного ключа?
WHEN new.id_item is NULL? и как присвоить ему значение последовательности?
new.id_item:=UNIQE_ID.nexval -- ругается..

Сообщение было отредактировано: 3 май 09, 19:47
3 май 09, 19:38    [7139978]     Ответить | Цитировать Сообщить модератору
 Re: Проблема с функциями pl/sql.  [new]
destr
Guest
CREATE OR REPLACE TRIGGER item_bi
   BEFORE INSERT
   ON item
   FOR EACH ROW
BEGIN
   SELECT uniqe_id.NEXTVAL
     INTO :NEW.id_item
     FROM DUAL;
END;
3 май 09, 20:30    [7140084]     Ответить | Цитировать Сообщить модератору
 Re: Проблема с функциями pl/sql.  [new]
Andrewshkovskii
Member

Откуда:
Сообщений: 40
Спасибо, но только здается мне что там не Each row надо пользовать, ведь условие : при введении нового значения, а не перелапачивать всю таблицу:)если я не прав - поправьте.
3 май 09, 20:32    [7140089]     Ответить | Цитировать Сообщить модератору
 Re: Проблема с функциями pl/sql.  [new]
destr
Guest
а что с функцией не так? компилится вроде... или возвращает что то не то?
3 май 09, 20:34    [7140091]     Ответить | Цитировать Сообщить модератору
 Re: Проблема с функциями pl/sql.  [new]
destr
Guest
кстати по триггеру правильнее будет так
CREATE OR REPLACE TRIGGER item_bi
   BEFORE INSERT
   ON item
   FOR EACH ROW
BEGIN
   IF :NEW.id_item IS NULL
   THEN
      SELECT uniqe_id.NEXTVAL
        INTO :NEW.id_item
        FROM DUAL;
   END IF;
END;

но нужно ошибки отслеживать на предмет вставки уникального значения, но лучше вставлять значение из последовательности безусловно.
3 май 09, 20:37    [7140095]     Ответить | Цитировать Сообщить модератору
 Re: Проблема с функциями pl/sql.  [new]
Andrewshkovskii
Member

Откуда:
Сообщений: 40
С функцией..ну главная проблема в самом задании.Не понятно что за дату надо смотреть.А возвращает она не то, видимо я как-то криво связал, ибо возвращает она item.rownum*rent.rownum*repair.rownum значений.
3 май 09, 20:40    [7140101]     Ответить | Цитировать Сообщить модератору
 Re: Проблема с функциями pl/sql.  [new]
destr
Guest
не очень понимаю постановку задачи, но в самой функции криминала особо нет, разве что для этого блока
IF sql%notFound THEN --если ничего не выбранно..
          dbms_output.put_line('No such item');
       END IF;
или добавить выход из функции или сделать raise_application_error, а ошибку отловить...

а так по условию или
SELECT getbalance (id_item, SYSDATE)
  FROM item;

или в PL/SQL блоке перебрать курсор вернет не более
select count(*) from item;
записей.
3 май 09, 20:58    [7140130]     Ответить | Цитировать Сообщить модератору
 Re: Проблема с функциями pl/sql.  [new]
Elic
Member

Откуда:
Сообщений: 29976
destr
но в самой функции криминала особо нет, разве что для этого блока
SELECT ... INTO ...;
IF sql%notFound THEN --если ничего не выбранно..
или добавить выход из функции или сделать raise_application_error, а ошибку отловить...
RTFM SELECT INTO Statement: Usage Notes (FAQ)
4 май 09, 08:36    [7140776]     Ответить | Цитировать Сообщить модератору
 Re: Проблема с функциями pl/sql.  [new]
Bogdanov Andrey
Member

Откуда: Да уже и сам не знаю...
Сообщений: 2203
Andrewshkovskii
Спасибо, но только здается мне что там не Each row надо пользовать, ведь условие : при введении нового значения, а не перелапачивать всю таблицу:)если я не прав - поправьте.
for each row означает, что действие выполняется для каждой модифицируемой (в данном случае для каждой добавляемой) строки, а не для всех строк таблицы.
4 май 09, 11:50    [7141735]     Ответить | Цитировать Сообщить модератору
Все форумы / Oracle Ответить