我有一个这样定义的Oracle序列:
CREATE SEQUENCE "DALLAS"."X_SEQ"
MINVALUE 0
MAXVALUE 999999999999999999999999999
INCREMENT BY 1 START WITH 0 NOCACHE NOORDER NOCYCLE ;
在存储过程中使用它来插入记录:
PROCEDURE Insert_Record
(p_name IN VARCHAR2,
p_userid IN INTEGER,
cur_out OUT TYPES_PKG.RefCursor)
IS
v_id NUMBER := 0;
BEGIN
-- Get id value from sequence
SELECT x_seq.nextval
INTO v_id
FROM dual;
-- Line below is X_PKG line 40
INSERT INTO X
(the_id,
name,
update_userid)
VALUES
(v_id,
p_name,
p_userid);
-- Return new id
OPEN cur_out FOR
SELECT v_id the_id
FROM dual;
END;
有时,此过程从应用程序代码执行时返回错误。
ORA-01400: cannot insert NULL into ("DALLAS"."X"."THE_ID")
ORA-06512: at "DALLAS.X_PKG", line 40
ORA-06512: at line 1
可能相关或可能不相关的详细信息:
- Oracle Database 11g企业版11.2.0.1.0版-64位生产
- 该过程通过Microsoft.Practices.EnterpriseLibrary-Data.Oracle.OracleDatabase.ExecuteReader(DbCommand命令)执行
- 应用程序不会将调用包装在显式事务中。
- 插入间歇性失败-少于1%
在什么情况下可以x_seq.nextval
为空?
选择和插入之间有多少代码?该代码中是否有任何BEGIN..END块或任何EXCEPTION语句?该代码中是否完全引用了v_id?似乎有点奇怪。您可以在语句之后直接放置“ IF v_id IS NULL THEN .... END IF”块,如果序列实际上确实为v_id分配了null,则可以在某些地方放置一些调试输出吗?该序列或将序列选择包装在BEGIN..EXCEPTION块中,因为可能发生了一些未被捕获的事件。最后一件事-您要插入的表上是否有触发器可能会导致该触发器?
—
Philᵀᴹ
@Phil-选择位于插入之前。除proc BEGIN / END外,没有BEGIN,END或EXCEPTION。
—
科宾2012年3
v_id
仅在序列选择,插入和最终光标中引用。我们的下一步是添加调试代码。我们可能要等待结果,因为它只会在生产中发生,而且很少出现。有一个触发器插入到审计表中。我已经没有抽烟了。有时在没有触发器的其他表中也会出现此问题。谢谢参观。
我目前唯一真正想到的是::new.the_id在表X的触发器中将以某种方式变为
—
NULL。
@Phil:这绝对是问题的原因。您应该将其作为答案。
—
勒内Nyffenegger
@RenéNyffenegger-在没有触发器的情况下插入表的proc中也会出现此问题。这似乎是机会均等的错误。
—
科宾2012年3