Plsql 在oracle中用默认值替换空值
请关注以下oracle初学者案例: 表“X”包含客户数据:Plsql 在oracle中用默认值替换空值,plsql,Plsql,请关注以下oracle初学者案例: 表“X”包含客户数据: ID Variable_A Variable_B Variable_C Variable_D -------------------------------------------------- 1 100 null abc 2003/07/09 2 null 2 null null Variable_name Defaul
ID Variable_A Variable_B Variable_C Variable_D
--------------------------------------------------
1 100 null abc 2003/07/09
2 null 2 null null
Variable_name Default_Value
----------------------------
Variable_A 50
Variable_B 0
Variable_C text
Variable_D sysdate
表“Dictionary”包含我们可以视为客户数据默认值的内容:
ID Variable_A Variable_B Variable_C Variable_D
--------------------------------------------------
1 100 null abc 2003/07/09
2 null 2 null null
Variable_name Default_Value
----------------------------
Variable_A 50
Variable_B 0
Variable_C text
Variable_D sysdate
目标是根据给定的ID检查“X”中的行,并用“Dictionary”中的默认值替换空值。具体的问题是关于最佳解决方案,因为现在我自己的解决方案是使用循环和MERGE-INTO语句,我认为这不是最佳的。另外,在“X”中添加新列时,有必要使用灵活的代码,而不必更改它。直接的方法是使用
update X set
variable_a = coalesce(variable_a, (select default_value from Dictionary where name = 'Variable_A')),
variable_b = coalesce(variable_b, (select default_value from Dictionary where name = 'Variable_B')),
... and so on ...
一般来说,它应该足够快 直接的方法是使用
update X set
variable_a = coalesce(variable_a, (select default_value from Dictionary where name = 'Variable_A')),
variable_b = coalesce(variable_b, (select default_value from Dictionary where name = 'Variable_B')),
... and so on ...
一般来说,它应该足够快 直接的方法是使用
update X set
variable_a = coalesce(variable_a, (select default_value from Dictionary where name = 'Variable_A')),
variable_b = coalesce(variable_b, (select default_value from Dictionary where name = 'Variable_B')),
... and so on ...
一般来说,它应该足够快 直接的方法是使用
update X set
variable_a = coalesce(variable_a, (select default_value from Dictionary where name = 'Variable_A')),
variable_b = coalesce(variable_b, (select default_value from Dictionary where name = 'Variable_B')),
... and so on ...
一般来说,它应该足够快 因为您不知道表X的哪些字段将为空,所以应该为每一行提供每个默认值。而且,由于X的每个字段可能是不同的数据类型,字典表应该在相应类型的字段中具有每个默认值。这种布局如图所示 显示X的每一行完全填充X中的值或其默认值的查询变得相对简单
select ID,
nvl( Var_A, da.Int_Val ) Var_A,
nvl( Var_B, db.Int_Val ) Var_B,
nvl( Var_C, dc.Txt_Val ) Var_C,
nvl( Var_D, dd.Date_Val ) Var_D
from X
join Dict da
on da.Name = 'VA'
join Dict db
on db.Name = 'VB'
join Dict dc
on dc.Name = 'VC'
join Dict dd
on dd.Name = 'VD';
将其转换为Update语句稍微复杂一点,但只要使用几次就足够简单了:
update X
set (Var_A, Var_B, Var_C, Var_D) =(
select nvl( Var_A, da.Int_Val ),
nvl( Var_B, db.Int_Val ),
nvl( Var_C, dc.Txt_Val ),
nvl( Var_D, dd.Date_Val )
from X InnerX
join Dict da
on da.Name = 'VA'
join Dict db
on db.Name = 'VB'
join Dict dc
on dc.Name = 'VC'
join Dict dd
on dd.Name = 'VD'
where InnerX.ID = X.ID )
where exists(
select 1
from X
where Var_A is null
or Var_B is null
or Var_C is null
or Var_D is null );
这有一个问题。日期类型的默认值为sysdate
,这意味着它将显示填充默认表的日期和时间,而不是执行更新的日期和时间。我想这不是你想要的。您可以尝试使用动态sql来实现这一切,但这将非常复杂。对于你想在这里做的事情来说太复杂了
我只看到两个现实的选择:要么将有意义的日期存储为默认日期(例如9999-12-31),要么只知道日期类型的每个默认值都是sysdate
,并在更新中使用它。在上述更新中,只需更改一行即可实现这一点:
nvl( Var_D, sysdate )
并且去掉最后一个连接。因为您不知道表X的哪些字段将为空,所以您应该为每一行提供每个默认值。而且,由于X的每个字段可能是不同的数据类型,字典表应该在相应类型的字段中具有每个默认值。这种布局如图所示 显示X的每一行完全填充X中的值或其默认值的查询变得相对简单
select ID,
nvl( Var_A, da.Int_Val ) Var_A,
nvl( Var_B, db.Int_Val ) Var_B,
nvl( Var_C, dc.Txt_Val ) Var_C,
nvl( Var_D, dd.Date_Val ) Var_D
from X
join Dict da
on da.Name = 'VA'
join Dict db
on db.Name = 'VB'
join Dict dc
on dc.Name = 'VC'
join Dict dd
on dd.Name = 'VD';
将其转换为Update语句稍微复杂一点,但只要使用几次就足够简单了:
update X
set (Var_A, Var_B, Var_C, Var_D) =(
select nvl( Var_A, da.Int_Val ),
nvl( Var_B, db.Int_Val ),
nvl( Var_C, dc.Txt_Val ),
nvl( Var_D, dd.Date_Val )
from X InnerX
join Dict da
on da.Name = 'VA'
join Dict db
on db.Name = 'VB'
join Dict dc
on dc.Name = 'VC'
join Dict dd
on dd.Name = 'VD'
where InnerX.ID = X.ID )
where exists(
select 1
from X
where Var_A is null
or Var_B is null
or Var_C is null
or Var_D is null );
这有一个问题。日期类型的默认值为sysdate
,这意味着它将显示填充默认表的日期和时间,而不是执行更新的日期和时间。我想这不是你想要的。您可以尝试使用动态sql来实现这一切,但这将非常复杂。对于你想在这里做的事情来说太复杂了
我只看到两个现实的选择:要么将有意义的日期存储为默认日期(例如9999-12-31),要么只知道日期类型的每个默认值都是sysdate
,并在更新中使用它。在上述更新中,只需更改一行即可实现这一点:
nvl( Var_D, sysdate )
并且去掉最后一个连接。因为您不知道表X的哪些字段将为空,所以您应该为每一行提供每个默认值。而且,由于X的每个字段可能是不同的数据类型,字典表应该在相应类型的字段中具有每个默认值。这种布局如图所示 显示X的每一行完全填充X中的值或其默认值的查询变得相对简单
select ID,
nvl( Var_A, da.Int_Val ) Var_A,
nvl( Var_B, db.Int_Val ) Var_B,
nvl( Var_C, dc.Txt_Val ) Var_C,
nvl( Var_D, dd.Date_Val ) Var_D
from X
join Dict da
on da.Name = 'VA'
join Dict db
on db.Name = 'VB'
join Dict dc
on dc.Name = 'VC'
join Dict dd
on dd.Name = 'VD';
将其转换为Update语句稍微复杂一点,但只要使用几次就足够简单了:
update X
set (Var_A, Var_B, Var_C, Var_D) =(
select nvl( Var_A, da.Int_Val ),
nvl( Var_B, db.Int_Val ),
nvl( Var_C, dc.Txt_Val ),
nvl( Var_D, dd.Date_Val )
from X InnerX
join Dict da
on da.Name = 'VA'
join Dict db
on db.Name = 'VB'
join Dict dc
on dc.Name = 'VC'
join Dict dd
on dd.Name = 'VD'
where InnerX.ID = X.ID )
where exists(
select 1
from X
where Var_A is null
or Var_B is null
or Var_C is null
or Var_D is null );
这有一个问题。日期类型的默认值为sysdate
,这意味着它将显示填充默认表的日期和时间,而不是执行更新的日期和时间。我想这不是你想要的。您可以尝试使用动态sql来实现这一切,但这将非常复杂。对于你想在这里做的事情来说太复杂了
我只看到两个现实的选择:要么将有意义的日期存储为默认日期(例如9999-12-31),要么只知道日期类型的每个默认值都是sysdate
,并在更新中使用它。在上述更新中,只需更改一行即可实现这一点:
nvl( Var_D, sysdate )
并且去掉最后一个连接。因为您不知道表X的哪些字段将为空,所以您应该为每一行提供每个默认值。而且,由于X的每个字段可能是不同的数据类型,字典表应该在相应类型的字段中具有每个默认值。这种布局如图所示 显示X的每一行完全填充X中的值或其默认值的查询变得相对简单
select ID,
nvl( Var_A, da.Int_Val ) Var_A,
nvl( Var_B, db.Int_Val ) Var_B,
nvl( Var_C, dc.Txt_Val ) Var_C,
nvl( Var_D, dd.Date_Val ) Var_D
from X
join Dict da
on da.Name = 'VA'
join Dict db
on db.Name = 'VB'
join Dict dc
on dc.Name = 'VC'
join Dict dd
on dd.Name = 'VD';
将其转换为Update语句稍微复杂一点,但只要使用几次就足够简单了:
update X
set (Var_A, Var_B, Var_C, Var_D) =(
select nvl( Var_A, da.Int_Val ),
nvl( Var_B, db.Int_Val ),
nvl( Var_C, dc.Txt_Val ),
nvl( Var_D, dd.Date_Val )
from X InnerX
join Dict da
on da.Name = 'VA'
join Dict db
on db.Name = 'VB'
join Dict dc
on dc.Name = 'VC'
join Dict dd
on dd.Name = 'VD'
where InnerX.ID = X.ID )
where exists(
select 1
from X
where Var_A is null
or Var_B is null
or Var_C is null
or Var_D is null );
这有一个问题。日期类型的默认值为sysdate
,这意味着它将显示填充默认表的日期和时间,而不是执行更新的日期和时间。我想这不是你想要的。您可以尝试使用动态sql来实现这一切,但这将非常复杂。对于你想在这里做的事情来说太复杂了
我只看到两个现实的选择:要么将有意义的日期存储为默认日期(例如9999-12-31),要么只知道日期类型的每个默认值都是sysdate
,并在更新中使用它。那会