我有一个表CONFIG_PRAM,其中包含colname
,datatype
等列以及现有表格的更多详细信息。
实施例
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中为此提供解决方案?
答案 0 :(得分:1)
此查询以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表的结构有一个正确的考虑:您在插入或更新时应用的规则越松散,在选择使用时您需要做的工作就越多。
答案 1 :(得分:0)
ALL_TAB_COLUMNS
包含的内容比data_type
多得多。您还需要至少比较data_length
,data_precision
和data_scale
。
您的联接也缺少table_name
和owner
,最好使用ANSI连接语法。