[英]Compare datatype of all the columns of tables with one configuration table in plsql
我有一个表CONFIG_PRAM,其中包含诸如colname
, datatype
以及现有表的更多详细信息之类的colname
。
例
CREATE TABLE CONFIG_PRAM
( colname varchar(40),
datatype varchar(40)
);
我必须将CONFIG_PRAM表中存在的那些列和数据类型与现有表的列进行比较。
示例:数据库中有一个现有的表test1表
create table test1 ( employee_id NUMBER(6),
sal NUMBER(6,8));
如果发现任何不匹配,我需要使用正确的数据类型更新CONFIG_PRAM表。
对于CONFIG_PRAM表中的上面一个,我们有sal number
但实际上它是表中的number(6,8)
,因此我必须用确切的数据类型更新CONFIG_PRAM表。
我已经这样尝试过:
select distinct colname , datatype
from CONFIG_PRAM , all_tab_columns
where upper(column_name)=upper(colname )
and data_type=datatype
and table_name in ('TEST1')
但是,假设表A具有Number(6,8)
并且CONFIG_PRAM表仅包含Number
那么它给出的结果不正确。 问题是此查询没有完全比较十进制值。 您能否在sql / PLSQL中为此提供解决方案?
该查询基于COLUMN_NAME将表连接到ALL_TAB_COLUMNS。 这意味着仅当CONFIG_PRAM仅具有一个表的条目时,它才能正常工作。 也许它也需要TABLE_NAME的列?
select cp.colname
, cp.datatype as config_datatype
, atc.data_type as actual_datatype
, atc.data_length as actual_length
, atc.data_precision as actual_precision
, atc.data_scale as actual_scale
from CONFIG_PRAM cp
join all_tab_columns atc
on atc.column_name = cp.colname
where atc.owner = user
and atc.table_name in ('TEST1')
and upper(cp.datatype) != case
when atc.data_type = 'VARCHAR2'
then atc.data_type||'('||atc.data_length||')'
when atc.data_type = 'NUMBER'
and instr(cp.datatype, ',') = 0
and atc.data_scale = 0
then atc.data_type||'('||atc.data_precision||')'
when atc.data_type = 'NUMBER'
then atc.data_type||'('||atc.data_precision||','||atc.data_scale||')'
else atc.data_type
end
;
WHERE子句将您的datatype
列与组合的数据类型字符串进行比较。 显然,潜在的数据类型比该查询处理的更多。 您将需要根据需要扩展它。 同样,数据类型字符串格式的变化也会产生误报。 因此,您应该对CONFIG_PRAM表的结构有一个适当的考虑:插入或更新时应用的规则越宽松,在选择使用表时就必须做更多的工作。
这是一个SQL Fiddle演示 。
ALL_TAB_COLUMNS
包含的列比data_type
还要多。 您还需要至少比较data_length
, data_precision
和data_scale
。
您的联接也缺少table_name
和owner
,最好使用ANSI联接语法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.