[英]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.