PL/SQL触发器编译报错:ORA-00920无效关系运算符
Oracle 19c触发器编译报错排查
环境:Oracle 19c(兼容12c)
以下是我的触发器代码:
CREATE OR REPLACE TRIGGER ClientTime AFTER INSERT OR UPDATE OR DELETE ON ClientTime FOR EACH ROW DECLARE v_pk_json CLOB; v_changed CLOB; v_old_part VARCHAR2(32767); v_new_part VARCHAR2(32767); v_first_old BOOLEAN; v_first_new BOOLEAN; BEGIN -- build pk json v_pk_json := '{' || CASE WHEN INSERTING OR UPDATING THEN '"id":' || NVL(TO_CHAR(:NEW.ID),'null') ELSE '"id":' || NVL(TO_CHAR(:OLD.ID),'null') END || '}'; -- build changed columns json IF INSERTING THEN v_changed := '{' || '"id":' || NVL(TO_CHAR(:NEW.ID), 'null') || ',' || '"client":' || NVL(TO_CHAR(:NEW.CLIENT), 'null') || ',' || '"timestamp":"' || NVL(TO_CHAR(:NEW.DATETIME, 'YYYY-MM-DD HH24:MI:SS'), 'null') || '"' || '}'; ELSIF DELETING THEN v_changed := '{' || '"id":' || NVL(TO_CHAR(:OLD.ID), 'null') || ',' || '"client":' || NVL(TO_CHAR(:OLD.CLIENT), 'null') || ',' || '"timestamp":"' || NVL(TO_CHAR(:OLD.DATETIME, 'YYYY-MM-DD HH24:MI:SS'), 'null') || '"' || '}'; ELSE -- UPDATE: only changed columns v_old_part := '{'; v_new_part := '{'; v_first_old := TRUE; v_first_new := TRUE; IF NVL(:OLD.CLIENT, -999999) <> NVL(:NEW.CLIENT, -999999) THEN v_old_part := v_old_part || '"client":' || NVL(TO_CHAR(:OLD.CLIENT),'null'); v_new_part := v_new_part || '"client":' || NVL(TO_CHAR(:NEW.CLIENT),'null'); v_first_old := FALSE; v_first_new := FALSE; END IF; IF NVL(:OLD.DATETIME, TO_DATE('1900-01-01','YYYY-MM-DD')) <> NVL(:NEW.DATETIME, TO_DATE('1900-01-01','YYYY-MM-DD')) THEN IF NOT v_first_old THEN v_old_part := v_old_part || ','; v_new_part := v_new_part || ','; END IF; v_old_part := v_old_part || '"timestamp":"' || NVL(TO_CHAR(:OLD.DATETIME,'YYYY-MM-DD HH24:MI:SS'),'null') || '"'; v_new_part := v_new_part || '"timestamp":"' || NVL(TO_CHAR(:NEW.DATETIME,'YYYY-MM-DD HH24:MI:SS'),'null') || '"'; END IF; v_old_part := v_old_part || '}'; v_new_part := v_new_part || '}'; v_changed := '{"old":' || v_old_part || ',"new":' || v_new_part || '}'; END IF; -- insert into audit_log INSERT INTO audit_log(change_txid, scn, change_ts, db_user, session_id, client_host, module_name, schema_name, table_name, op_type, pk_json, changed_columns) VALUES (DBMS_TRANSACTION.LOCAL_TRANSACTION_ID, ORA_ROWSCN, SYSTIMESTAMP, SYS_CONTEXT('USERENV','SESSION_USER'), SYS_CONTEXT('USERENV','SESSIONID'), SYS_CONTEXT('USERENV','HOST'), SYS_CONTEXT('USERENV','MODULE'), 'DBNAME','CLIENTTIME', CASE WHEN INSERTING THEN 'I' WHEN UPDATING THEN 'U' ELSE 'D' END, v_pk_json, v_changed); END;
注:为安全起见修改了列名,实际中Datetime并非Oracle关键字。
编译报错:
PL/SQL: SQL Statement ignored
PL/SQL: ORA-00920: invalid relational operator
我已尝试以下修改但均无效:
- 将
SYS_CONTEXT('USERENV', 'SESSION_USER')改为USER - 将
SYS_CONTEXT('USERENV', 'SESSIONID')改为SESSIONID - 将
SYS_CONTEXT('USERENV', 'HOST')改为HOST - 提前INSERT语句中的CASE逻辑
我认为代码存在结构性问题但无法定位。
更新:将INSERT语句修改为以下内容后,触发器已编译成功:
INSERT INTO audit_log(change_txid, scn, change_ts, db_user, session_id, client_host, module_name, schema_name, table_name, op_type, pk_json, changed_columns) VALUES (NULL, NULL, SYSDATE, USER, NULL, NULL,NULL, 'DBNAME','CLIENTTIME', 'I', v_pk_json, v_changed);
内容的提问来源于stack exchange,提问作者davejal
相关产品推荐
相关产品推荐

