【发布时间】:2021-12-12 21:21:34
【问题描述】:
导入包含触发器的 dp 转储文件会出现错误 ORA-39083 和 ORA-04079。 我在 Windows 10 上使用 Oracle XE 11g 64 位。 我导出了一个包含状态为“VALID”的触发器的架构。 当我在同一个数据库(但不同的架构)中再次导入转储文件时,它会引发上述异常。
导入日志显示失败的 SQL。 但是,它只显示了 CREATE TRIGGER-sql 的一部分。 接下来是导出和导入日志,以及相关的触发器。
导出日志
;;;
Export: Release 11.2.0.2.0 - Production on Wed Oct 27 16:42:13 2021
Copyright (c) 1982, 2009, Oracle and/or its affiliates. All rights reserved.
;;;
Connected to: Oracle Database 11g Express Edition Release 11.2.0.2.0 - 64bit Production
Starting "VBSDB"."SYS_EXPORT_SCHEMA_01": VBSDB/********@XE DIRECTORY=VBS DUMPFILE=20211027_164212_$VBSDB.dpdmp LOGFILE=20211027_164212_$VBSDB.dplog VERSION=11 EXCLUDE=STATISTICS
Estimate in progress using BLOCKS method...
Processing object type SCHEMA_EXPORT/TABLE/TABLE_DATA
Total estimation using BLOCKS method: 3.812 MB
Processing object type SCHEMA_EXPORT/PRE_SCHEMA/PROCACT_SCHEMA
Processing object type SCHEMA_EXPORT/TYPE/TYPE_SPEC
Processing object type SCHEMA_EXPORT/SEQUENCE/SEQUENCE
Processing object type SCHEMA_EXPORT/TABLE/TABLE
Processing object type SCHEMA_EXPORT/TABLE/INDEX/INDEX
Processing object type SCHEMA_EXPORT/TABLE/CONSTRAINT/CONSTRAINT
Processing object type SCHEMA_EXPORT/TABLE/COMMENT
Processing object type SCHEMA_EXPORT/FUNCTION/FUNCTION
Processing object type SCHEMA_EXPORT/FUNCTION/ALTER_FUNCTION
Processing object type SCHEMA_EXPORT/VIEW/VIEW
Processing object type SCHEMA_EXPORT/TABLE/CONSTRAINT/REF_CONSTRAINT
Processing object type SCHEMA_EXPORT/TABLE/TRIGGER
Processing object type SCHEMA_EXPORT/TABLE/INDEX/FUNCTIONAL_AND_BITMAP/INDEX
...
. . exported "VBSDB"."FIN_BETALING" 0 KB 0 rows
...
Master table "VBSDB"."SYS_EXPORT_SCHEMA_01" successfully loaded/unloaded
******************************************************************************
Dump file set for VBSDB.SYS_EXPORT_SCHEMA_01 is:
D:\DATABASES\20211027_164212_$VBSDB.DPDMP
Job "VBSDB"."SYS_EXPORT_SCHEMA_01" successfully completed at 16:42:27
导入日志
;;;
;;;
Import: Release 11.2.0.2.0 - Production on Wed Oct 27 16:42:35 2021
Copyright (c) 1982, 2009, Oracle and/or its affiliates. All rights reserved.
;;;
Connected to: Oracle Database 11g Express Edition Release 11.2.0.2.0 - 64bit Production
Master table "VBSDB2"."SYS_IMPORT_SCHEMA_01" successfully loaded/unloaded
Starting "VBSDB2"."SYS_IMPORT_SCHEMA_01": USERID=VBSDB2/********@XE directory=VBS dumpFILE=20211027_164212_$VBSDB.DPDMP logfile=271021164234.oracleimplog.txt schemas=VBSDB remap_schema=VBSDB:VBSDB2 transform=oid:n
Processing object type SCHEMA_EXPORT/PRE_SCHEMA/PROCACT_SCHEMA
Processing object type SCHEMA_EXPORT/TYPE/TYPE_SPEC
Processing object type SCHEMA_EXPORT/SEQUENCE/SEQUENCE
Processing object type SCHEMA_EXPORT/TABLE/TABLE
Processing object type SCHEMA_EXPORT/TABLE/TABLE_DATA
...
. . imported "VBSDB2"."FIN_BETALING" 0 KB 0 rows
...
Processing object type SCHEMA_EXPORT/TABLE/INDEX/INDEX
Processing object type SCHEMA_EXPORT/TABLE/CONSTRAINT/CONSTRAINT
Processing object type SCHEMA_EXPORT/FUNCTION/FUNCTION
Processing object type SCHEMA_EXPORT/FUNCTION/ALTER_FUNCTION
Processing object type SCHEMA_EXPORT/VIEW/VIEW
Processing object type SCHEMA_EXPORT/TABLE/CONSTRAINT/REF_CONSTRAINT
Processing object type SCHEMA_EXPORT/TABLE/TRIGGER
ORA-39083: Object type TRIGGER failed to create with error:
ORA-04079: invalid trigger specification
Failing sql is:
CREATE TRIGGER "VBSDB2"."T_FIN_BETALING_DELETE"
BEFORE DELETE
ON FIN_BETALING
FOR EACH ROW
WHEN (OLD.VERREKENINGFACTUURREGELID IS NOT NULL) V_MSG := 'De betaling-id ' || TO_CHAR(:OLD.FIN_BETALINGID) || ' is reeds doorgestort en kan derhalve niet verwijderd worden'; IF V_AFREKENINGID IS NOT NULL THEN V_MSG := V_MSG || ' (afrekening-id ' || TO_CHAR(V_AFREKENINGID) || ', beheer
Processing object type SCHEMA_EXPORT/TABLE/INDEX/FUNCTIONAL_AND_BITMAP/INDEX
Job "VBSDB2"."SYS_IMPORT_SCHEMA_01" completed with 1 error(s) at 16:42:44
触发器
CREATE TRIGGER VBSDB.T_FIN_BETALING_DELETE
BEFORE DELETE
ON VBSDB.FIN_BETALING
FOR EACH ROW
WHEN (OLD.VERREKENINGFACTUURREGELID IS NOT NULL)
DECLARE
V_AFREKENINGID NUMBER;
V_BOVK VARCHAR2(50 CHAR);
V_MSG VARCHAR2(255 CHAR);
BEGIN
SELECT A.PRG_AFREKENINGID,
C.CONTRACTNRSTR
INTO V_AFREKENINGID,
V_BOVK
FROM FIN_FACTUURREGEL FR
JOIN FIN_FACTUUR F
ON FR.FIN_FACTUURID = F.FIN_FACTUURID
JOIN PRG_CONTRACT C
ON C.PRG_CONTRACTID = F.PRG_CONTRACTID
JOIN PRG_AFREKENING A
ON F.BEHFACTAFREKENINGID = A.PRG_AFREKENINGID
WHERE FR.FIN_FACTUURREGELID = :OLD.VERREKENINGFACTUURREGELID;
V_MSG := 'De betaling-id ' || TO_CHAR(:OLD.FIN_BETALINGID) || ' is reeds doorgestort en kan derhalve niet verwijderd worden';
IF V_AFREKENINGID IS NOT NULL
THEN
V_MSG := V_MSG || ' (afrekening-id ' || TO_CHAR(V_AFREKENINGID) || ', beheerovereenkomst ' || V_BOVK || ')';
END IF;
RAISE_APPLICATION_ERROR(-20500, V_MSG);
END;
/
事实证明,仅当 CREATE TRIGGER-sql 通过 .NET 和 ODT for Visual Studio 2019 (ODP.net 4.122.19.1) 执行时才会出现问题。 但是,通过 System.Data.OracleClient 命名空间执行 SQL 时也会出现问题。 当通过 DBForge 执行相同的 CREATE TRIGGER-sql 时,则导出和导入成功。虽然,在第一种情况下,Oracle 无法成功完成抽水工作是很奇怪的,因为触发器具有 VALID 状态。
我使用的代码:
private const string SQL = @"CREATE OR REPLACE TRIGGER T_FIN_BETALING_DELETE
BEFORE DELETE
ON FIN_BETALING
FOR EACH ROW
WHEN (OLD.VERREKENINGFACTUURREGELID IS NOT NULL)
DECLARE
V_AFREKENINGID NUMBER;
V_BOVK VARCHAR2(50 CHAR);
V_MSG VARCHAR2(255 CHAR);
BEGIN
SELECT
A.PRG_AFREKENINGID,
C.CONTRACTNRSTR INTO V_AFREKENINGID, V_BOVK
FROM
FIN_FACTUURREGEL FR
JOIN FIN_FACTUUR F on FR.FIN_FACTUURID = F.FIN_FACTUURID
JOIN PRG_CONTRACT C ON C.PRG_CONTRACTID = F.PRG_CONTRACTID
JOIN PRG_AFREKENING A on F.BEHFACTAFREKENINGID = A.PRG_AFREKENINGID
WHERE FR.FIN_FACTUURREGELID = :OLD.VERREKENINGFACTUURREGELID;
V_MSG := 'De betaling-id ' || TO_CHAR(:OLD.FIN_BETALINGID) || ' is reeds doorgestort en kan derhalve niet verwijderd worden';
IF V_AFREKENINGID IS NOT NULL THEN
V_MSG := V_MSG || ' (afrekening-id ' || TO_CHAR(V_AFREKENINGID) || ', beheerovereenkomst ' || V_BOVK || ')';
END IF;
RAISE_APPLICATION_ERROR(-20500, V_MSG);
END;";
private static void CreateTrigger(OracleConnection connection)
{
using (var cmd = new OracleCommand(SQL, connection))
{
cmd.ExecuteNonQuery();
}
}
我已尝试更改 CREATE TRIGGER 语句的结尾部分:
- 通过添加/删除';'
- 通过添加/删除 CRLF
- 通过添加/删除“\”
任何偏离上述 SQL 语句的变体都会导致触发器进入 INVALID 状态。
剩下的问题是:是什么导致 ODP.net 创建了一个状态为 VALID 的 Oracle 触发器,该触发器无法使用数据泵再次导出和导入?
任何帮助将不胜感激!
【问题讨论】:
-
导入完成后触发器在目标模式中是否处于无效状态?如果是这样,如果你尝试编译触发器,你会得到什么错误?
-
@RobertoHernandez 触发器在目标模式 (VBSDB2) 中不存在。
-
你能运行这个吗?
impdp USERID=xxxx directory=xxx dumpfile=xxxxx logfile=xxxx.txt remap_schema=VBSDB:VBSDB2 include=trigger content=metadata_only -
@RobertoHernandez 它给出了 ORA-04079: invalid trigger specification。
-
我尝试在 Oracle EE 中复制您的问题,使用带或不带引号的数据泵触发器导入/导出我没有任何问题。我怀疑您的问题可能与 Oracle XE 以及您使用的那个非常旧的版本有关
标签: database oracle datapump impdp