【问题标题】:Error ORA-54033 when calling a procedure调用过程时出现错误 ORA-54033
【发布时间】:2015-11-17 23:54:56
【问题描述】:

我目前在调用过程时遇到以下 Oracle 错误:

ORA-54033: 要修改的列在虚拟列中使用 表达

你知道我怎样才能找到这个错误的根本原因吗?

【问题讨论】:

  • @BootStrapper 我没有使用扩展统计信息。
  • 请提供过程调用...
  • 您正在调用的过程正在尝试更新用于计算虚拟列的“真实”列的数据类型。正如@BootStrapper 指出的那样,这可能是由于使用扩展统计信息(您声明您没有这样做)引起的,或者可能只是表中有一个虚拟列使用该过程试图更改的“真实”列.祝你好运。
  • @BobJarvis 有什么办法可以列出我数据库中的所有虚拟列吗?

标签: database oracle oracle12c


【解决方案1】:

要查找数据库中所有虚拟列的表名和列名,您可以运行以下查询:

SELECT c.OWNER, c.TABLE_NAME, c.COLUMN_NAME
  FROM DBA_TAB_COLS c
  WHERE c.VIRTUAL_COLUMN = 'YES' AND
        c.OWNER NOT IN ('SYS', 'XDB')
  ORDER BY c.OWNER, c.TABLE_NAME, c.COLUMN_NAME;

您可以使用以下脚本将数据库中包含虚拟列的所有表的 DDL 转储到 DBMS_OUTPUT:

DECLARE 
  lobDDL  CLOB;

  PROCEDURE dump_clob(aCLOB IN CLOB) IS
    nCLOB_length       NUMBER;
    nCLOB_offset       NUMBER := 1;
    nMax_chunk_size    NUMBER := 32767;
    strChunk           VARCHAR2(32767);
  BEGIN
    nCLOB_length := DBMS_LOB.GETLENGTH(aCLOB);

    WHILE nCLOB_offset <= nCLOB_length LOOP
      strChunk := DBMS_LOB.SUBSTR(aCLOB, nMax_chunk_size, nCLOB_offset);

      DBMS_OUTPUT.PUT(strChunk);

      nCLOB_offset := nCLOB_offset + LENGTH(strChunk);
    END LOOP;

    DBMS_OUTPUT.PUT_LINE(';');
  END dump_clob;
BEGIN
  FOR aRow IN (SELECT DISTINCT c.OWNER, c.TABLE_NAME
                 FROM DBA_TAB_COLS c
                 WHERE c.VIRTUAL_COLUMN = 'YES' AND
                       c.OWNER NOT IN ('SYS', 'XDB')
                 ORDER BY c.OWNER, c.TABLE_NAME)
  LOOP
    lobDDL := DBMS_METADATA.GET_DDL(object_type => 'TABLE',
                                    name        => aRow.TABLE_NAME,
                                    schema      => aRow.OWNER);

    dump_clob(lobDDL);
  END LOOP;
END;

祝你好运。

【讨论】:

  • 感谢您的询问。我现在在我的表上找到了一些虚拟列,但它们的名称类似于SYS_STSERN5WA2$#_GOCGFGAEQSSAF。这个名字是否对应什么?我怎样才能摆脱那些虚拟列?
  • 几乎所有以SYS 开头的东西都是系统生成的。当然它对应于某些东西,但没有看到相关表的完整 DDL,我什至无法猜测它可能是什么。您可以尝试编辑您的问题并包括表格的 DDL。祝你好运。
【解决方案2】:

我遇到了同样的错误,通过以下操作修复。

使用下面的方法获取隐藏列及其依赖列。

SELECT COLUMN_NAME, DATA_DEFAULT, HIDDEN_COLUMN
FROM   USER_TAB_COLS
WHERE  TABLE_NAME = 'YOUR_TABLE_NAME';

你应该会在下面看到一些这样的

SYS_STUMF_$2WEF286CDZ1WPC4V_F5  |SYS_OP_COMBINED_HASH("ID","FIRST_NAME","ANOTHER_COLUMN_NAME") | YES

使用上面使用的列名删除此隐藏列。

exec dbms_stats.drop_extended_stats(user, 'YOUR_TABLE_NAME', '("ID","FIRST_NAME","ANOTHER_COLUMN_NAME") ');

现在运行您的程序或更改您的列。

alter table YOUR_TABLE_NAME modify (ID VARCHAR2(10));

再次创建隐藏列

exec dbms_stats.create_extended_stats(user, 'YOUR_TABLE_NAME', '("ID","FIRST_NAME","ANOTHER_COLUMN_NAME")');

【讨论】:

  • 我也遇到了这个错误,但这是在修改列的数据类型而不是调用过程时。无论如何,jajikanth-pydimarla 提供的解决方案仍然是可行的,应该标记为正确答案。
【解决方案3】:

以 'SYS_ST%' 开头的虚拟列名确实属于扩展集统计信息......并且由于 oracle 12c 系统正在尝试自动识别和创建它们......只需谷歌搜索“oracle 12c 自动列组检测”

【讨论】:

    猜你喜欢
    • 2021-11-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-05
    • 1970-01-01
    • 2012-08-25
    • 1970-01-01
    • 2018-02-14
    相关资源
    最近更新 更多