1

我设计了一个流程,将视图中的数据复制到 oracle 中的相应表中。我所做的就是调用一个传递“视图名称”作为参数的过程,这会创建相应的表(如果不存在,则删除并创建表)。所以这是动态发生的,我有大约 50 个视图,它们被安排为 oracle 作业。

现在问题来了,我有一些表在某些日子里失败并出现以下错误......

ORA-01723: 不允许零长度列

我知道造成这种情况的原因是视图中的几列为空,但并非整天如此。是的,我应该对这些列使用 CAST,但是正如我提到的,这种情况是动态发生的,我不知道这些列是哪一列或那是哪个视图?在我开始创建表之前,任何可以确定视图中是否存在“零长度列”的线索,以便我可以想到一些解决方案。对此的任何更好的补救措施都非常感谢。

笔记:

  1. CREATE TABLE TABLE_NAME AS SELECT * FROM VIEW_NAME --> 这是我的表创建 SQL。
  2. 我选择这个的原因是“INSERT INTO”可能会因为日志记录和锁定而花费更多的时间和资源。

谢谢,娜迦'

4

2 回答 2

1

正如你所说,你调用一个过程来从视图中创建一个表。所以我假设您已经在使用动态 SQL(Native Dynamic SQL aka EXECUTE IMMEDIATEstatement or DBMS_SQLpackage)来执行 DDL 语句。CREATE TABLE AS然后,您可以使用 Oracle 字典视图(如USER_VIEWSUSER_TAB_COLUMNS )生成更复杂的语句,以获取有关列类型、长度、比例以及编写正确 CAST 调用可能需要的任何其他信息。

下面是一个肮脏的例子:

create or replace view v 
as 
  select decode(dummy, 'Y', '123') s 
       , 1 n
       , 2.2 f
       , cast (1.1 as number(5,3)) fs
    from dual
/

set serveroutput on
declare
  l_query varchar2(32767) := 'create table t as select <column list> from v';
  l_type varchar2(100);
begin
  for tc in (
    select * from user_tab_columns 
     where table_name = 'V'
     order by column_id
  ) loop
    l_type := tc.data_type;
    l_type := l_type || 
      case tc.data_type 
        when 'NUMBER' then 
          case when tc.data_precision is not null then '(' || tc.data_precision || case when tc.data_scale is not null then ','||tc.data_scale end || ')' end
        when 'VARCHAR2' then 
          '(' || tc.char_length || ' ' || case tc.char_used when 'C' then 'char' else 'byte' end || ')' 
       end;
    l_query := replace(l_query, '<column list>', 'cast("'||tc.column_name||'" as '|| l_type ||') "'||tc.column_name||'" ,<column list>');
  end loop;
  l_query := replace(l_query, ',<column list>');

  dbms_output.put_line(l_query);
end;
/

结果:

view V created.
anonymous block completed
create table t as select cast("S" as VARCHAR2(3 char)),cast("N" as NUMBER),cast("F" as NUMBER),cast("FS" as NUMBER(5,3)) from v

祝你好运。

于 2013-06-05T14:54:11.640 回答
0

我选择这个的原因是“INSERT INTO”可能会因为日志记录和锁定而花费更多的时间和资源。

我认为您每次删除和重新创建表格的方法都是基于错误的信念。截断它们并使用直接路径插入,可选地不记录,会给你几乎相同的结果而没有这个问题。如果您正在使用:

create table .. as select from ...

...那么无论如何您都在完全记录操作。

于 2013-06-05T15:52:51.777 回答