Oracle 查询 all_tab_columns.data_default(LONG 类型)

Posted

技术标签:

【中文标题】Oracle 查询 all_tab_columns.data_default(LONG 类型)【英文标题】:Oracle query all_tab_columns.data_default (type LONG) 【发布时间】:2017-07-10 10:05:53 【问题描述】:

我已经运行了这个查询:

SELECT
    OWNER,
    TABLE_NAME,
    COLUMN_NAME,
    DATA_TYPE,
    DATA_LENGTH,
    (CASE
        WHEN DATA_PRECISION IS NULL THEN 0
        ELSE DATA_PRECISION
     END) DATA_PRECISION,
    (CASE
        WHEN DATA_SCALE IS NULL THEN 0
        ELSE DATA_SCALE
     END) DATA_SCALE,
    NULLABLE,
    COLUMN_ID
    DEFAULT_LENGTH,
    DATA_DEFAULT,
    (CASE
        WHEN DATA_DEFAULT IS NULL THEN '0'
        ELSE DATA_DEFAULT
     END) DATA_DEFAULT1
FROM 
    all_tab_columns
WHERE 
    table_name LIKE 'TABLE1';

但它在DATA_DEFAULT 列抛出错误:

ORA-00932:不一致的数据类型:预期的 CHAR 得到了 LONG 00932. 00000 - “不一致的数据类型:预期的 %s 得到了 %s”

我该如何解决这个问题?

谢谢!

【问题讨论】:

DATA_PRECISIONDATA_SCALEDATA_DEFAULT 的类型有哪些? 问题很可能在于您的一个或多个CASE 表达式。 你在COLUMN_ID之后忘记了, 这里是所有列类型的解释:docs.oracle.com/cd/B19306_01/server.102/b14237/… 我在 COLUMN_ID 之后放了 , 但问题在于 DATA_DEFAULT 类型为 LONG。 【参考方案1】:

LONG 无能为力。这是一个 PITA,Oracle 仍然在数据字典中使用它们。

您可以使用 XML:

select owner
     , table_name
     , column_name
     , data_type
     , data_length
     , case
           when data_precision is null then 0
           else data_precision
       end data_precision
     , case
           when data_scale is null then 0
           else data_scale
       end data_scale
     , nullable
     , column_id
     , default_length
     , case
           when default_length is null then '0'
           else
               extractvalue
               ( dbms_xmlgen.getxmltype
                 ( 'select data_default from user_tab_columns where table_name = ''' || c.table_name || ''' and column_name = ''' || c.column_name || '''' )
               , '//text()' )
       end as data_default
from   all_tab_columns c
where  table_name like 'TABLE1';

从 12.1 开始,您可以编写自己的内联查找函数:

with
     function get_default(tab varchar2, col varchar2) return varchar2
     as
         dflt varchar2(4000);
     begin
         select c.data_default into dflt
         from   user_tab_columns c
         where  c.table_name = upper(tab)
         and    c.column_name = upper(col);
         
         return dflt;
     end get_default;
select owner
     , table_name
     , column_name
     , data_type
     , data_length
     , case
           when data_precision is null then 0
           else data_precision
       end data_precision
     , case
           when data_scale is null then 0
           else data_scale
       end data_scale
     , nullable
     , column_id
     , default_length
     , get_default(c.table_name, c.column_name) as data_default
from   all_tab_columns c
where  table_name like 'TABLE1%'
/

或者当然是做一个独立的函数或者包函数来做同样的事情。

【讨论】:

工作得很好! 我必须用 ( 'select data_default from all_tab_columns where table_name = ''' || c.table_name || ''' and owner = ''' || c.owner || ''' and column_name = ''' || c.column_name || '''' ) 替换内部行才能正常工作。 @MikhailOrlov 不,你不必那样做。【参考方案2】:

这里是一些如何打印 LONG 的代码。您可以随意更改。

set serveroutput on
declare
  cursor c1 is
  select 
  OWNER
    ,TABLE_NAME
    ,COLUMN_NAME
    ,DATA_TYPE
    ,DATA_LENGTH
    ,(CASE WHEN DATA_PRECISION IS NULL THEN 0 ELSE DATA_PRECISION END) DATA_PRECISION
    ,(CASE WHEN DATA_SCALE IS NULL THEN 0 ELSE DATA_SCALE END) DATA_SCALE
    ,NULLABLE
    ,COLUMN_ID
    ,DEFAULT_LENGTH
    ,DATA_DEFAULT
  from all_Tab_columns where table_name='ENTITIES' and default_length is not null;
v_long long;
v_varchar2 varchar2(4000);
begin
  for loop1 in c1
  loop
    v_long := loop1.DATA_DEFAULT;
    v_varchar2 := substr(v_long,1,4000);
    dbms_output.put_line(v_varchar2); 
  end loop;
end;

【讨论】:

谢谢,但我需要一个没有光标的简单查询。 我也想知道如何在没有光标的情况下显示 LONG。 @sandman - 将此答案更改为函数定义并将其用法合并到上面的查询中。那么它可能看起来像一个答案,因为现在您只是在建议一种显示长值的方法。 @g00dy 我正是在暗示这一点,因为他的问题在于 long 和显示默认值。我相信海报可以按照你的建议做:) @sandman,我同意,但是由于这个函数应该在查询中使用,它可能会进入一个视图并且可能会进入一个要创建的表,那么这个函数应该返回一个值。您会建议它应该返回什么类型的值等以及如何正确使用它。我只是在这里说...这是以防万一您投反对票并想知道为什么会这样..(虽然不是从我这里得到的)

以上是关于Oracle 查询 all_tab_columns.data_default(LONG 类型)的主要内容,如果未能解决你的问题,请参考以下文章

Oracle SQL:从 all_tab_columns 中选择未找到现有列

oracle数据库如何查询表结构

查询oracle表中字段中某数据的命令

oracle判断表是不是存在字段

oracle中怎么用sql查表以及表的字段名

用oracle查询表字段的的数据类型怎么查?