1

I have data as below in csv format and uploading this data into table:

TABLE NAME: MYDATA

+----+-------+-------+---------+
| ID | NAME  | STATE |  CODE   |
+----+-------+-------+---------+
|  1 | P&P   | AQ    | BIN1234 |
|  2 | ABC   | AQ    | BIN5678 |
|  3 | G-I   | AQ    | BIN3457 |
|  4 | MC-DO | AQ    | BIN3462 |
|  5 | TEC   | AQ    | ERP9756 |
|  6 | CBA   | BT    | ERP4353 |
|  7 | W&X   | BT    | ERP5456 |
|  8 | P-Q   | GH    | ERP3457 |
+----+-------+-------+---------+

Trying to achieve below conditions based on data:

  1. Delete values from STATE column where value is not equal to 'AQ'.
  2. Delete values from CODE column where value like '%ERP%'.
  3. Replace special characters AMPERSAND '&' and HYPHEN '-' with UNDERSCORE '_' from NAME column.
  4. Trim whitespaces from NAME column.

Wrote below trigger but getting error:

CREATE OR replace TRIGGER BI_MYDATA_TR
  BEFORE INSERT OR UPDATE ON MYDATA
BEGIN
    DELETE FROM MYDATA
    WHERE  upper(state) <> 'AQ'
    OR upper(code) LIKE '%ERP%'; 

    :NEW.name := trim(regexp_replace(:NEW.name, '&|-', '_'));
END; 

Below is the error I am getting:

Error at line 3: PL/SQL: Statement ignored Error at line 3: PLS-00201: identifier 'NEW.NAME' must be declared

  1. create or replace trigger BI_MYDATA_TR
  2. before insert or update on MYDATA
  3. begin
  4. DELETE FROM MYDATA WHERE upper(state) <> 'AQ' OR upper(code) LIKE '%ERP%';
  5. :NEW.name := trim(regexp_replace(:NEW.name, '&|-', '_'));

Appreciate if I get any help on how to combine these multiple conditions in one trigger.

Thanks in advance.

Thanks,

Richa

Solution posted by @Florin worked and updating my code below since adding code in comments section was not formatting:

CREATE OR replace TRIGGER BIU_MYDATA_TR
  BEFORE INSERT OR UPDATE ON MYDATA
  REFERENCING NEW AS NEW OLD AS OLD
FOR EACH ROW
BEGIN
    DELETE FROM MYDATA
    WHERE  upper(STATE) <> 'AQ'
    OR upper(CODE) LIKE '%ERP%'; 

    :NEW.NAME := trim(regexp_replace(:NEW.NAME, '&|-', '_'));
END; 
3
  • You need to use :new (with colon) to reference the values of row being inserted. But the target table doesn't contain the data you are inserting, so delete statement will not affect new data
    – astentx
    Commented Jun 27, 2022 at 17:49
  • Apart from that, the easiest way to insert the data from a CSV file (as a one-time operation) is to use SQL Loader, where you may conditionally clean up the data before insert (without triggers) and perform bulk insert.
    – astentx
    Commented Jun 27, 2022 at 17:51
  • @astentx, thank you for response. I have colon in actual code. It's the typo in OP, will update it now. I am working on Oracle APEX and loading data from data workshop. Hence need this trigger.
    – Richa
    Commented Jun 28, 2022 at 5:01

2 Answers 2

1
After BEFORE INSERT OR UPDATE ON MYDATA
i will put 
  REFERENCING NEW AS NEW OLD AS OLD
FOR EACH ROW
Begin .....
3
  • thank you for your answer. This solved the issue. Below is the updated code: `CREATE OR replace TRIGGER BIU_MYDATA_TR BEFORE INSERT OR UPDATE ON MYDATA REFERENCING NEW AS NEW OLD AS OLD FOR EACH ROW BEGIN DELETE FROM MYDATA WHERE upper(STATE) <> 'AQ' OR upper(CODE) LIKE '%ERP%'; :NEW.NAME := trim(regexp_replace(:NEW.NAME, '&|-', '_')); END; '
    – Richa
    Commented Jul 3, 2022 at 16:03
  • I am not able to format code in comments though I added backtick character by following this link: meta.stackexchange.com/questions/74784/…. Hence will update the OP. Thank you
    – Richa
    Commented Jul 3, 2022 at 16:05
  • @ Richa to format the code use ctrl+k after you have selected everything
    – Florin
    Commented Jul 3, 2022 at 16:17
0

It looks like there is no column NAME in your table.

In addition, your requirement is

Delete values from STATE column where value is not equal to 'AQ'.

Does it mean that you want to delete the value from the triggered row? If it does, then your logic of "DELETE FROM MYDATA where ..." is incorrect - it will delete rows, not values from the triggered row. The correct way is

if upper(:new.state) <> 'AQ' then 
   :new.state := null;
end if;
2
  • sorry for my English. Delete statement is correct. I need entire row to be deleted. I do not want nulls to be inserted. Thank you
    – Richa
    Commented Jun 28, 2022 at 19:26
  • @Richa If you liked my answer you can upvote it and/or accept it as an answer
    – Michael
    Commented Jun 29, 2022 at 9:37

Not the answer you're looking for? Browse other questions tagged or ask your own question.