Oracle 无法从现有列填充表中的新列

Oracle 无法从现有列填充表中的新列,oracle,plsql,triggers,Oracle,Plsql,Triggers,我有一张桌子。它的结构如下: CREATE TABLE cars ( ID NUMBER(38) PRIMARY KEY, Manufacturer VARCHAR2(26), Model VARCHAR2(26), Year NUMBER(38), Category VARCHAR2(26), Mileage NUMBER(38), FuelType VARCHAR2(26), EngineVolume VARCHAR2(26), DriveWheels

我有一张桌子。它的结构如下:

CREATE TABLE cars ( 
  ID NUMBER(38) PRIMARY KEY,
  Manufacturer VARCHAR2(26),
  Model VARCHAR2(26),
  Year NUMBER(38),
  Category VARCHAR2(26),
  Mileage NUMBER(38),
  FuelType VARCHAR2(26),
  EngineVolume VARCHAR2(26),
  DriveWheels VARCHAR2(26),
  GearBox VARCHAR2(26),
  Doors VARCHAR2(26),
  Wheel VARCHAR2(26),
  Color VARCHAR2(26),
  InteriorColor VARCHAR2(26),
  VIN VARCHAR2(26),
  LeatherInterior VARCHAR2(26),
  Price NUMBER(38),
  Clearance VARCHAR2(26),
  Age NUMBER(38),
  PriceInTg NUMBER(38)
 )  
 INSERT INTO CARS (ID, MANUFACTURER, MODEL, YEAR, CATEGORY, MILEAGE, FUELTYPE, ENGINEVOLUME, DRIVEWHEELS, GEARBOX, DOORS, WHEEL, COLOR, INTERIORCOLOR, VIN, LEATHERINTERIOR, PRICE, CLEARANCE)
 VALUES (0,'BMW','M6',2014,'Coupe',33500,'Petrol','4.4','Rear','Tiptronic','4/5','Left wheel','White','Black','','true',39000,'false');
我想填充从其他列填充的
age
和'pricintg'列。因此,我为它创建了填充函数:

CREATE OR REPLACE FUNCTION age_converter(Year NUMBER) 
RETURN NUMBER
IS
v_age Number;
BEGIN
    v_age := EXTRACT(YEAR FROM SYSDATE) - Year;
    RETURN v_age;
END;


CREATE OR REPLACE FUNCTION price_converter(Price NUMBER, currency_in_tg NUMBER)
RETURN NUMBER
IS
price_in_tg NUMBER;
BEGIN 
    price_in_tg := Price  * currency_in_tg;
    RETURN price_in_tg;
END;
为了自动填充这些列,我创建了触发器:

CREATE OR REPLACE TRIGGER age_filler_trigger
AFTER INSERT ON cars FOR EACH ROW
BEGIN
    INSERT INTO cars (age)
    VALUES (age_converter(:OLD.year));
END;

CREATE OR REPLACE TRIGGER priceTg_filler 
AFTER INSERT ON cars FOR EACH ROW
BEGIN
    INSERT INTO cars (age)
    VALUES (price_converter(:OLD.price, 430));
END;
但当我像这样向表中插入值时:

CREATE TABLE cars ( 
  ID NUMBER(38) PRIMARY KEY,
  Manufacturer VARCHAR2(26),
  Model VARCHAR2(26),
  Year NUMBER(38),
  Category VARCHAR2(26),
  Mileage NUMBER(38),
  FuelType VARCHAR2(26),
  EngineVolume VARCHAR2(26),
  DriveWheels VARCHAR2(26),
  GearBox VARCHAR2(26),
  Doors VARCHAR2(26),
  Wheel VARCHAR2(26),
  Color VARCHAR2(26),
  InteriorColor VARCHAR2(26),
  VIN VARCHAR2(26),
  LeatherInterior VARCHAR2(26),
  Price NUMBER(38),
  Clearance VARCHAR2(26),
  Age NUMBER(38),
  PriceInTg NUMBER(38)
 )  
 INSERT INTO CARS (ID, MANUFACTURER, MODEL, YEAR, CATEGORY, MILEAGE, FUELTYPE, ENGINEVOLUME, DRIVEWHEELS, GEARBOX, DOORS, WHEEL, COLOR, INTERIORCOLOR, VIN, LEATHERINTERIOR, PRICE, CLEARANCE)
 VALUES (0,'BMW','M6',2014,'Coupe',33500,'Petrol','4.4','Rear','Tiptronic','4/5','Left wheel','White','Black','','true',39000,'false');
我犯了这样的错误:

Error starting at line : 6 in command -
INSERT INTO CARS (ID, MANUFACTURER, MODEL, YEAR, CATEGORY, MILEAGE, FUELTYPE, ENGINEVOLUME, DRIVEWHEELS, GEARBOX, DOORS, WHEEL, COLOR, INTERIORCOLOR, VIN, LEATHERINTERIOR, PRICE, CLEARANCE) VALUES (0,'BMW','M6',2014,'Coupe',33500,'Petrol','4.4','Rear','Tiptronic','4/5','Left wheel','White','Black','','true',39000,'false')
Error report -
ORA-04091: table PROJECT.CARS is mutating, trigger/function may not see it
ORA-06512: at "PROJECT.PRICETG_FILLER", line 2
ORA-04088: error during execution of trigger 'PROJECT.PRICETG_FILLER'

如何处理该问题?

您的插入触发器不应该尝试插入新行。相反,他们应该设置
:新的
值,例如

:NEW.year := age_converter(:OLD.year);
我打算建议同时制作
AGE
PRICE
虚拟列,但这些列不能使用
sysdate
,因此动态计算年龄是个问题。但这是一个问题,因为您设置的任何值都只会反映行上次更新时的年龄,这可能是过去的任何时间,因此永远不会可靠。最好在
cars
表上创建一个视图,这样可以包含一个反映查询时间的年龄列

“tg中的价格”列可以是虚拟的:

priceintg number(38) generated always as (price * 430)

插入触发器不应该尝试插入新行。相反,他们应该设置
:新的
值,例如

:NEW.year := age_converter(:OLD.year);
我打算建议同时制作
AGE
PRICE
虚拟列,但这些列不能使用
sysdate
,因此动态计算年龄是个问题。但这是一个问题,因为您设置的任何值都只会反映行上次更新时的年龄,这可能是过去的任何时间,因此永远不会可靠。最好在
cars
表上创建一个视图,这样可以包含一个反映查询时间的年龄列

“tg中的价格”列可以是虚拟的:

priceintg number(38) generated always as (price * 430)

我可以发誓几天前我在另一个帖子上看到了同一张桌子。让我来观察一下这个设计。您似乎专注于26个字符作为字符列,38个数字作为数字列。这只是懒惰,毫无意义。一年38位数?里程数?等等,等等,等等。我以前在汽车行业工作,知道VIN固定在13个字符。发动机的体积不是立方英寸就是立方厘米——一个数字,不是字符。我可以发誓,我几天前在另一篇文章中看到了同样的表格。让我来观察一下这个设计。您似乎专注于26个字符作为字符列,38个数字作为数字列。这只是懒惰,毫无意义。一年38位数?里程数?等等,等等,等等。我以前在汽车行业工作,知道VIN固定在13个字符。发动机容积是立方英寸或立方厘米-一个数字,而不是字符。