我有一个带有两个模式的Oracle数据库。一个是旧的,另一个是新的。我想用新模式的新列更新旧模式。
我通过以下查询得到了更改的表。
select distinct table_name
from
(
select table_name,column_name
from all_tab_cols
where owner = 'SCHEMA_1'
minus
select table_name,column_name
from all_tab_cols
where owner = 'SCHEMA_2'
)
通过这个查询,我得到了表格。如何使用新列更新旧架构表?我不需要数据,只需要列。
答案 0 :(得分:5)
架构比较工具是个好主意。数据库模式比大多数人信任的要复杂得多,两个数据库模式之间的每个差异都有可能导致错误。
如果您仍然热衷于自己动手,我发现的最佳方法是将模式定义提取到文本,然后运行文本比较。只要所有内容都按字母顺序排序,您就可以使用Microsoft Word(或FC.EXE,DIFF或同等版本)中的比较文档功能来突出显示差异。
以下SQLPlus脚本按字母顺序输出架构定义,以便进行比较。有两个部分。第一部分按以下格式列出每列:
table_name.column_name: data_type = data_default <nullable>
第二部分列出了索引和约束,如下所示:
PK constraint_name on table_name (pk_column_list)
FK constraint_name on table_name (fk_column_list)
CHECK constraint_name on table_name (constraint_definition)
该脚本可作为提取某些Oracle架构详细信息的有用参考。当您在客户端站点上并且没有可用的常用工具时,或者当安全策略阻止您直接从您自己的PC访问客户端站点数据库时,这可能是一个很好的知识。
set serveroutput on;
set serveroutput on size 1000000;
declare
rowcnt pls_integer := 0;
cursor c_column is
select table_name, column_name, data_type,
data_precision, data_length, data_scale,
data_default, nullable,
decode(data_scale, null, null, ',') scale_comma,
decode(default_length, null, null, '= ') default_equals
from all_tab_columns where owner = 'BCC'
order by table_name, column_name;
cursor c_constraint is
select c.table_name, c.constraint_name,
decode(c.constraint_type,
'P','PK',
'R','FK',
'C','CHECK',
c.constraint_type) constraint_type,
c.search_condition,
cc.column_1||cc.comma_2||cc.column_2||cc.comma_3||cc.column_3||cc.comma_4||cc.column_4||
cc.comma_5||cc.column_5||cc.comma_6||cc.column_6||cc.comma_7||cc.column_7 r_columns
from all_constraints c,
( select owner, table_name, constraint_name, nvl(max(position),0) max_position,
max( decode( position, 1, column_name, null ) ) column_1,
max( decode( position, 2, decode(column_name, null, null, ',' ), null ) ) comma_2,
max( decode( position, 2, column_name, null ) ) column_2,
max( decode( position, 3, decode(column_name, null, null, ',' ), null ) ) comma_3,
max( decode( position, 3, column_name, null ) ) column_3,
max( decode( position, 4, decode(column_name, null, null, ',' ), null ) ) comma_4,
max( decode( position, 4, column_name, null ) ) column_4,
max( decode( position, 5, decode(column_name, null, null, ',' ), null ) ) comma_5,
max( decode( position, 5, column_name, null ) ) column_5,
max( decode( position, 6, decode(column_name, null, null, ',' ), null ) ) comma_6,
max( decode( position, 6, column_name, null ) ) column_6,
max( decode( position, 7, decode(column_name, null, null, ',' ), null ) ) comma_7,
max( decode( position, 7, column_name, null ) ) column_7
from all_cons_columns
group by owner, table_name, constraint_name ) cc
where c.owner = 'BCC'
and c.generated != 'GENERATED NAME'
and cc.owner = c.owner
and cc.table_name = c.table_name
and cc.constraint_name = c.constraint_name
order by c.table_name,
decode(c.constraint_type,
'P','PK',
'R','FK',
'C','CHECK',
c.constraint_type) desc,
c.constraint_name;
begin
for c_columnRow in c_column loop
dbms_output.put_line(substr(c_columnRow.table_name||'.'||c_columnRow.column_name||': '||
c_columnRow.data_type||'('||
nvl(c_columnRow.data_precision, c_columnRow.data_length)||
c_columnRow.scale_comma||c_columnRow.data_scale||') '||
c_columnRow.default_equals||c_columnRow.data_default||
' <'||c_columnRow.nullable||'>',1,255));
rowcnt := rowcnt + 1;
end loop;
for c_constraintRow in c_constraint loop
dbms_output.put_line(substr(c_constraintRow.constraint_type||' '||c_constraintRow.constraint_name||' on '||
c_constraintRow.table_name||' ('||
c_constraintRow.search_condition||
c_constraintRow.r_columns||') ',1,255));
if length(c_constraintRow.constraint_type||' '||c_constraintRow.constraint_name||' on '||
c_constraintRow.table_name||' ('||
c_constraintRow.search_condition||
c_constraintRow.r_columns||') ') > 255 then
dbms_output.put_line('... '||substr(c_constraintRow.constraint_type||' '||c_constraintRow.constraint_name||' on '||
c_constraintRow.table_name||' ('||
c_constraintRow.search_condition||
c_constraintRow.r_columns||') ',256,251));
end if;
rowcnt := rowcnt + 1;
end loop;
end;
/
不幸的是,有一些限制:
即使您不使用该脚本。玩这种东西有一定的技术乐趣。 ; - )
马修
答案 1 :(得分:3)
我担心此刻我不能为你做更多事情,但这应该给你一个基本的想法。
选择ADD
和DROP
列语句,您可以在仔细审核后执行 。
它无法处理
ALTER TABLE MODIFY
)DEFAULT VALUES
(因此,当新列为NOT NULL
时,您无法将其应用于包含数据的表格)我尝试了一些基本数据类型(NUMBER
,VARCHAR2
,DATE
)并且它有效。祝你好运:)
SELECT 'ALTER TABLE ' || LOWER(table_name)
|| ' ADD ' || LOWER(column_name) || ' ' || data_type
|| CASE WHEN data_type NOT IN ('DATE') THEN '(' || data_length || ')' END
|| CASE WHEN nullable='Y' THEN ' NOT NULL' END
|| ';' cmd
FROM all_tab_cols c2
WHERE owner = 'SCHEMA_1'
AND NOT EXISTS ( SELECT 1
FROM all_tab_cols c1
WHERE owner = 'SCHEMA_2'
AND c1.table_name = c2.table_name
AND c1.column_name = c2.column_name )
UNION ALL
SELECT 'ALTER TABLE ' || LOWER(table_name)
|| ' DROP COLUMN ' || LOWER(column_name) || ';'
FROM all_tab_cols c2
WHERE owner = 'SCHEMA_2'
AND NOT EXISTS ( SELECT 1
FROM all_tab_cols c1
WHERE owner = 'SCHEMA_1'
AND c1.table_name = c2.table_name
AND c1.column_name = c2.column_name )
ORDER BY cmd;
答案 2 :(得分:3)
我开始为此写一个答案,但我的警告列表变得比答案更长,所以我决定废弃它。
您应该使用架构比较工具。
有免费版本 - 请查看服务器故障上的这个问题:
https://serverfault.com/questions/26360/how-can-i-diff-two-oracle-10g-schemas
我的建议是下载Oracle的SQL Developer并使用内置的架构差异工具(尽管这要求您拥有Change Management Pack许可证)。