SQL Server в Oracle Language Translator - PullRequest
       9

SQL Server в Oracle Language Translator

0 голосов
/ 19 сентября 2018

У меня есть триггер, созданный в Microsoft SQL Server, который я пытаюсь перенести в Oracle SQL Developer.Я понимаю, что синтаксис и язык немного отличаются.Я медленно, но верно пытаюсь пройтись по каждой линии, но любая помощь или совет очень ценятся.

Триггер в Microsoft SQL Server, который я пытаюсь перенести в Oracle:

CREATE TRIGGER Production.Product_Price_Check
ON AdventureWorks.Production.Product FOR UPDATE
AS 
    DECLARE @min_price money; --to keep minimum price
    DECLARE @new_price money; --to keep new price from update query

    SELECT @min_price = (SELECT StandardCost*1.2 FROM INSERTED);
    SELECT @new_price = (SELECT ListPrice FROM INSERTED)
    IF @new_price < @min_price
       BEGIN
            ROLLBACK TRANSACTION
            -- Rolls back an explicit or implicit transaction to the beginning of the transaction
            PRINT('the price can’t be below ' + cast(@min_price as varchar(20)));
            -- cast is used to convert one data type to another one 
            RAISERROR ('statement was aborted', 6, 1) ;
            return; 
    ELSE PRINT ('Price was successfully changed');     
    END   

GO

Я буду публиковать обновления, где я нахожусь с новым триггером, поскольку я исследую:

UPDATE Product set ListPrice=42.00 WHERE ProductID=514;

Обновленный код:

CREATE OR REPLACE
TRIGGER Product_Price_Check
   BEFORE UPDATE ON Product
   FOR EACH ROW
       BEGIN
         IF :new.listprice < :new.standardcost * 1.2 then
         raise_application_error(-20999, 'The price can not be below' || to_char(:new.standardcost * 1.2));
         RETURN;
         ELSE
           dbms_output.put_line('Price was sucessfully changed');
         END IF;
END;

Пример кода для быстрого создания используемой таблицы:

CREATE TABLE Product(
    productID int Primary Key,
    name VARCHAR(250),
    ListPrice int Primary Key,
    StandardCost NUMBER(10,4),
);

INSERT INTO Product VALUES(514, 'NLL Mountain Seat Assembly', 133.3400, 98.7700);

Ответы [ 2 ]

0 голосов
/ 19 сентября 2018

Наиболее фундаментальное различие между триггерами в Oracle и SQL Server заключается в том, что Oracle использует по умолчанию триггеры уровня , что недоступно в SQL Server.Насколько я могу судить, все, что вы хотите сделать, это проверить, соответствуют ли новые значения обновленной строки определенным правилам.

CREATE or replace TRIGGER Product_Price_Check_trg
  BEFORE UPDATE ON Product 
  FOR EACH ROW -- this makes it a row level trigger
AS 
begin
  if :new.listprice < :new.standardcost * 1.2 then 
    raise_application_error(-20999, 'The price can''t be below ' || to_char(:new.listprice));
  end if;
end;
/

Из-за исключения транзакция, выполняющая это, должна быть откатана.

Подробнее о синтаксисе и примерах создания триггера можно найти в руководстве .


Однако триггер не нужен, ограничение проверки будет намного более эффективным (как в Oracle, так и в SQL Server)

create table product
(
   standardcost number,
   listprice    number, 
   constraint check_price check (listprice < standardcost * 1.2)
);
0 голосов
/ 19 сентября 2018

В Oracle или SQL Server, похоже, что триггер не нужен, и вместо этого следует написать:

ALTER TABLE Production.Product ADD CONSTRAINT CK_Product_Prices
CHECK (ListPrice >=StandardCost * 1.2);

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

...