В выражении SQL MErge говорится, что первичный ключ нарушен - PullRequest
0 голосов
/ 13 октября 2019

Я создал следующие таблицы.

CREATE TABLE FROOMSERVICEDATA 
(  
  TimeID Number(5) REFERENCES FTimePeriod(TimeID) NOT NULL, 
  RoomID Number(5) REFERENCES FRoom(RoomID) NOT NULL,  
  RoomType_ID Number(5) REFERENCES FROOMTYPE(RoomTypeID) NOT NULL,
  RoomServiceRevenueGenerated Number(10,2) NOT NULL, 
  TotalOrders Number(10,2) NOT NULL, 
  CONSTRAINT RoomServiceDataIDPK  PRIMARY KEY (TimeID, RoomType_ID, RoomID)  
);


CREATE TABLE FTIMEPERIOD 
(  
  TimeID Number(5),
  CalendarDate  DATE,
  CONSTRAINT ftimeperiodid  PRIMARY KEY (TimeID)  
);

и несколько других, которые не слишком важны

Я также создал следующий вид для работы с

CREATE OR REPLACE VIEW RoomServiceInsertView AS
SELECT s.request_id, s.bill_amount, s.request_date, r.ROOM_ID, tp.TimeID, r.ROOM_TYPE_ID
   FROM room_service_request s, room r, ftimeperiod tp
   WHERE   (r.room_id = s.room_id) AND (s.request_date = tp.CALENDARDATE);
   SELECT * FROM RoomServiceInsertView;

Теперь я пытаюсь запустить следующеезаявление слияния.

    MERGE INTO froomservicedata rsd
    USING (SELECt * FROM RoomServiceView) rsr
    ON ((rsr.ROOM_TYPE_ID = rsd.ROOMTYPE_ID) AND (rsd.TimeID = rsr.TimeID) AND (rsr.ROOM_ID  =  rsd.ROOMID ))
    WHEN MATCHED THEN 
        UPDATE SET 
        rsd.ROOMSERVICEREVENUEGENERATED = rsd.ROOMSERVICEREVENUEGENERATED + rsr.bill_amount,
        rsd.TOTALORDERS= rsd.TOTALORDERS +1
    WHEN NOT MATCHED THEN
        INSERT VALUES(rsr.TimeID, 
                      rsr.ROOM_ID, 
                      rsr.ROOM_TYPE_ID,
                      rsr.bill_amount
                      ,1);

Но мне говорят, что ограничение Первичного ключа RoomServiceDataIDPK нарушено, но мой оператор слияния не должен препятствовать этому. Если timeID, roomId и roomtypeID записи совпадают, то она должна быть обновлена, если я не ошибаюсь, но я думаю, что она пытается вставить и таким образом нарушить ограничение. Любой совет, почему это может происходить?

Ответы [ 2 ]

1 голос
/ 13 октября 2019

Ваше представление RoomServiceDataIDPK имеет одинаковые значения (TimeID, RoomType_ID, RoomID) в более чем одной строке.

Если бы эта же комбинация уже была в froomservicedata, вы получите исключение "ORA-30926: не удалосьчтобы получить стабильный набор строк в источнике ".

Поскольку комбинация не найдена в froomservicedata, MERGE пытается вставить все эти строки в froomservicedata, что вызывает исключение"ORA-00001: уникальное ограничение ".

Чтобы найти дубликаты, попробуйте это:

select * from (
  select r.*,
  count(*) over(partition by ROOM_TYPE_ID, TimeID, ROOM_ID) cnt
  from RoomServiceInsertView r
)
where cnt > 1
order by cnt desc, ROOM_TYPE_ID, TimeID, ROOM_ID;

С уважением, Стью Эштон

1 голос
/ 13 октября 2019

Я думаю, что у вас есть данные в RoomServiceView, которые нарушают первичный ключ на FROOMSERVICEDATA.

Я ожидаю, что попытка добавить тот же первичный ключ

 CONSTRAINT RoomServiceDataIDPK  PRIMARY KEY (TimeID, RoomType_ID, RoomID)

к RoomServiceView поможет вам выяснить проблемные данные.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...