首页 > 解决方案 > SQL Server 到 Oracle 语言翻译器

问题描述

我在 Microsoft SQL Server 中创建了一个触发器,我试图将其引入 Oracle SQL Developer。我意识到语法和语言有点不同。我正在缓慢但肯定地尝试通过每一行,但非常感谢任何帮助或指导。

我试图转移到 Oracle 的 Microsoft SQL Server 中的触发器:

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);

标签: oracleplsqldatabase-trigger

解决方案


在 Oracle 或 SQL Server 中,触发器似乎是不必要的,而您应该编写:

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

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


推荐阅读