OCI_CONNECT是否会导致ORA-01438:值大于此列允许的指定精度?

时间:2011-09-13 14:30:25

标签: php oracle ora-01438

我想知道oci_connect()是否会导致1438错误,因为我总是得到这个:

  

警告:oci_connect()[function.oci-connect]:ORA-00604:错误   发生在递归SQL级别1 ORA-01438:值大于   此列ORA-06512允许的指定精度:在第8行中   第220行/xxxxxx/some.php

这不取决于正在查询的表。似乎oci_connect()在某些sys表中插入了一些trackingstaff,或者触发器与登录有关。但我没有权限在sys中找出这个问题。

任何想法可能导致此错误的原因是什么?

更新

oracle是否在没有配置的情况下自动在框中自动进行某些日志记录?我可以以某种方式让oracle或PHP向我显示哪个表或列受到影响吗?

更新 我发现,当我直接在Bash中调用PHP脚本时,它确实可以正常工作。但来自网络的电话会引起标题问题。有什么想法吗?

2 个答案:

答案 0 :(得分:1)

消息error occurred at recursive SQL level 1向我建议错误是在触发器中出现的。我的猜测是有AFTER LOGON ON SCHEMADATABASE触发器,并且由于某种原因,当您的Web服务器进程尝试连接时,它会导致错误。

以下是如何生成您获得的错误的示例。我有一个名为TINY的表,其中一个列只能采用最多99的值:

SQL> desc tiny;
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 N                                                  NUMBER(2)

现在让我们创建一个用户帐户并验证他们是否可以连接:

SQL> create user fred identified by fred account unlock;

User created.

SQL> grant connect to fred;

Grant succeeded.

SQL> connect fred/fred
Connected.

好 - 让我以我身份重新登录并创建一个触发器,如果​​FRED尝试连接,将导致错误:

SQL> connect luke/password
Connected.
SQL> create or replace trigger after_logon_error_if_fred
  2    after logon on database
  3  begin
  4    if user = 'FRED' then
  5      insert into tiny (n) values (100);
  6    end if;
  7  end;
  8  /

Trigger created.

回想一下,我们的TINY表只能存储最多99个值。那么,当FRED尝试连接时会发生什么?

SQL> connect fred/fred
ERROR:
ORA-00604: error occurred at recursive SQL level 1
ORA-01438: value larger than specified precision allowed for this column
ORA-06512: at line 3

除了行号和PHP添加的位之外,这正是你得到的消息。

如果您想查看数据库中是否有AFTER LOGON个触发器,请尝试运行查询

SELECT trigger_name, owner FROM all_triggers
 WHERE TRIM(triggering_event) = 'LOGON';

在我的数据库(Oracle 11g XE beta)上,我得到以下输出:

TRIGGER_NAME                   OWNER
------------------------------ ------------------------------
AFTER_LOGON_ERROR_IF_FRED      LUKE

我不相信Oracle可以开箱即用,如果PHP的oci_connect也这样做,我会感到惊讶。

我只能推测为什么错误仅出现在您的Web服务器上,而不是从bash脚本运行PHP时。也许触发器是查询V$SESSION并试图找出用户帐户尝试连接到数据库的位置?

答案 1 :(得分:0)

好吧,根据列,您要么尝试插入的数字大于numeric列的允许范围,要么尝试将字符串插入varchar2(n)长度超过n个字符的列。 Here更详细地介绍了Oracle数据类型。

如果没有更详细的信息,我们在some.php的第220行的哪个表格中插入了哪些内容,我就无法提供更直接的帮助。