SQL Server到Oracle语言翻译器

Sam*_*Sam 3 oracle plsql database-trigger

我在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
Run Code Online (Sandbox Code Playgroud)

在我正在研究时,我将使用新触发器发布更新到我所处的位置:

UPDATE Product set ListPrice=42.00 WHERE ProductID=514;
Run Code Online (Sandbox Code Playgroud)

更新的代码:

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;
Run Code Online (Sandbox Code Playgroud)

快速创建我正在使用的表的示例代码:

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);
Run Code Online (Sandbox Code Playgroud)

Dam*_*ver 6

在Oracle或SQL Server中,看起来触发器是不必要的,你应该写什么:

ALTER TABLE Production.Product ADD CONSTRAINT CK_Product_Prices
CHECK (ListPrice >=StandardCost * 1.2);
Run Code Online (Sandbox Code Playgroud)

这样可以避免编写任何过程逻辑,而是使用声明性规则.这些通常是首选,因为有时,优化器可以利用它们来消除不可能产生任何结果的查询部分.


a_h*_*ame 5

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;
/
Run Code Online (Sandbox Code Playgroud)

由于异常,执行此操作的事务必须回滚.

有关如何创建触发器的语法和示例的更多详细信息,请参见手册


但是没有必要对一个触发器,检查约束会很多更有效率(在Oracle一样好,在SQL Server)

create table product
(
   standardcost number,
   listprice    number, 
   constraint check_price check (listprice < standardcost * 1.2)
);
Run Code Online (Sandbox Code Playgroud)