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_PRECISION
、DATA_SCALE
、DATA_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 类型)的主要内容,如果未能解决你的问题,请参考以下文章