PL / SQL Как получить количество таблицы, из которой я запрашиваю? Как использовать NEW с COUNT? - PullRequest
0 голосов
/ 06 мая 2020

ниже - это мой код, который срабатывает при вставке новой строки в Trip. Затем он обновится в столбце totalTripMade в таблице драйверов.

CREATE OR REPLACE TRIGGER UPDATE_TOTAL_TRIPS_MADE
AFTER INSERT
      ON TRIP
      FOR EACH ROW 

DECLARE 
    tripsDone NUMBER(6);
    driverL# NUMBER(12);

BEGIN
    --Find the L# of the Driver performing the INSERT into the Trip table
    SELECT D.L# INTO driverL#
    FROM DRIVER D
    WHERE D.L# =: NEW.L#;

    --Find the number of trips done by the driver (Error occured here)
    SELECT COUNT(T#) INTO tripsDone
    FROM TRIP T
    WHERE NEW.L# =: driverL#;

    --Then update the totaltripmade by the driver
    UPDATE 
        DRIVER
    SET
        totalTripMade = tripsDone
    WHERE
        L# = driverL#;
END UPDATE_TOTAL_TRIPS_MADE;
/

Однако есть ошибка компиляции из-за невозможности запросить TRIP до завершения триггера. Итак, я попытался изменить оператор select count на это:

SELECT COUNT(*) INTO tripsDone
FROM TRIP T
WHERE driverL# =: NEW.L#;

Но это тоже не сработало. Я не уверен, как мне обойтись, чтобы получить общее количество строк в таблице Trip с драйвером L #, который вызвал триггер.

1 Ответ

0 голосов
/ 11 мая 2020

Для решения этой проблемы вам, вероятно, НЕ следует использовать триггер. Просто напишите запрос на подсчет "поездок". Пример:

Таблицы

create table driver (
  id number generated always as identity start with 1 primary key
, surname varchar2( 50 )
-- , ttm number -- total trips made: redundant!
) ;

create table trip (
  id number generated always as identity start with 1000 primary key
, from_ varchar2( 50 )
, to_   varchar2( 50 )
, driver number references driver( id )
) ;

Тестовые данные: DRIVER

insert into driver( surname )
select 
  'driver_' || to_char( level )
from dual
connect by level <= 10 ;

select * from driver ;
  ID SURNAME     
   1 driver_1    
   2 driver_2    
   3 driver_3    
   4 driver_4    
   5 driver_5    
   6 driver_6    
   7 driver_7    
   8 driver_8    
   9 driver_9    
  10 driver_10

Тестовые данные: TRIP

begin
  for i in 1 .. 10
  loop
    insert into trip ( from_, to_, driver ) values ( 
      'departure_' || to_char( i )
    , 'arrival_' || to_char( i )
    , mod( i, 3 ) + 1
    ) ;
  end loop ;
  commit ;
end ;
/

SQL> select * from trip ;
    ID FROM_          TO_            DRIVER 
  1000 departure_1    arrival_1           2 
  1001 departure_2    arrival_2           3 
  1002 departure_3    arrival_3           1 
  1003 departure_4    arrival_4           2 
  1004 departure_5    arrival_5           3 
  1005 departure_6    arrival_6           1 
  1006 departure_7    arrival_7           2 
  1007 departure_8    arrival_8           3 
  1008 departure_9    arrival_9           1 
  1009 departure_10   arrival_10          2 

Запрос: найдите «количество поездок»

select D.id, D.surname, count(*) as trips_made
from driver D 
  join trip T on D.id = T.driver
group by D.id, D.surname ;

-- result
  ID SURNAME      TRIPS_MADE 
   1 driver_1              3 
   2 driver_2              4 
   3 driver_3              3 

Однако, если вы хотите узнать о триггерах, вы обнаружите, что «триггер на уровне строки» даст вам ошибки «изменяющейся таблицы». При использовании триггера «табличного уровня» нельзя ссылаться на: NEW и: OLD. Что вам нужно, так это СЛОЖНЫЙ ТРИГГЕР. Вы можете найти множество дискуссий по этой проблеме. Помимо ознакомления с документацией Oracle PL / SQL , возможно, стоит посмотреть, что примеры, написанные Т. Холлом, например здесь , и S Feuerstein например здесь .

dbfiddle здесь содержит код, использованный для этого ответа, и третью таблицу примеров с именем DRIVERV2 плюс примеры вышеупомянутых типов триггеров (и типичные сообщения об ошибках).

...