Oracle - 如何在加载时添加新列并设置默认值

时间:2015-03-25 17:46:28

标签: oracle performance

我有一个oracle数据库,其中一个表包含货币字段:

desc example_table;
Name      Null     Type
--------- -------- ------
...
PRICE     NOT NULL NUMBER
SHIPPING           NUMBER
DISCOUNT           NUMBER
...

我需要修改此表格,以便还包含每个字段的相应货币代码。并且需要使用与已存在的列对应的默认值填充这些新列。

以下是我对如何做到这一点的想法:

alter table example_table add (
    price_currency_code    varchar2(3)
  , shipping_currency_code varchar2(3)
  , discount_currency_code varchar2(3)
);

update example_table
   set price_currency_code = 'USD'
     , shipping_currency_code = case when shipping is null 
                                     then null 
                                     else 'USD' 
                                end
     , discount_currency_code = case when discount is null 
                                     then null 
                                     else 'USD' 
                                end
;

最后,我需要确保每个新列的可空属性与原始列的可空属性匹配:

alter table example_table modify (
    price_currency_code varchar2(3) not null
);

这是解决此问题的正确(和最佳性能)解决方案吗?是否有另一种方法可以实现在包含数亿行的表上可能表现更好的相同结果?

如果使用此方法更新网站的生产表,此更新在更新运行时如何影响网站上的用户体验?

1 个答案:

答案 0 :(得分:2)

你可以使用Justin提到的技巧,例如:

alter table example_table add (
    price_currency_code    varchar2(3) default 'USD' not null
  , shipping_currency_code varchar2(3)
  , discount_currency_code varchar2(3)
);

alter table example_table modify price_currency_code default null;

这允许您将所有现有行设置为'USD',但不保留后续插入的默认行。当然,如果'USD'是合理的默认值,那么您可以跳过第二个alter

然后,这只是其他专栏的问题。根据满足条件的行数,您可以选择一个或两个更新语句,例如:

update example_table set shipping_currency_code = 'USD' where shipping is not null;
update example_table set discount_currency_code = 'USD' where discount is not null;

如果涉及大量记录,您可能需要采用不同的策略。

要考虑的另一个选择是使用DBMS_REDEFINITION