首页 > 解决方案 > 根据取自另一表的值更新一个表的日期字段

问题描述

我有两个表 A 和 B,它们都有日期字段,但格式不同('MM/DD/YYYY HH:MI:SS' 和 'MM/DD/YYYY'),它们都有一个名为 invoiced_value 的公共字段。我需要从表 B(带有'MM/DD/YYYY')的值更新表 A(带有'MM/DD/YYYY HH:MI:SS')的日期值。我可以使用以下查询吗?我可以像这样附加日期 to_date(e.invoiced_date ||' 3:56:24', 'MM/DD/YYYY HH:MI:SS') 吗?

  UPDATE Table1
  SET m.invoiced_date = to_date(e.invoiced_date ||' 3:56:24', 'MM/DD/YYYY HH:MI:SS')
  FROM Table2 e, Table1 m
  WHERE m.invoiced_value = e.invoiced_value

标签: sqldatejoinoracle11gsql-update

解决方案


[TL;DR]使用MERGE语句:

MERGE INTO Table1 dst
USING Table2 src
ON ( src.invoiced_value = dst.invoiced_value )
WHEN MATCHED THEN
  UPDATE SET invoiced_date = TRUNC( src.invoiced_date ) + INTERVAL '3:56:24' HOUR TO SECOND;

我可以使用以下查询吗?

不,UPDATE语句没有FROM子句。您将需要使用相关的子查询或MERGE语句。

我可以像这样附加日期to_date(e.invoiced_date ||' 3:56:24', 'MM/DD/YYYY HH:MI:SS')吗?

也许......但你不应该这样做。TO_DATE( string_value, format_model )将字符串作为第一个参数(||字符串连接运算符也需要字符串参数进行连接),因此您e.invoiced_date将从 a 隐式转换为DATE字符串,并且您的表达式有效:

to_date(
  TO_CHAR(
    e.invoiced_date,
    ( SELECT value FROM NLS_SESSION_PARAMETERS WHERE PARAMETER = 'NLS_DATE_FORMAT' )
  ) || ' 3:56:24',
  'MM/DD/YYYY HH:MI:SS'
)

如果您的NLS_DATE_FORMAT会话参数是,MM/DD/YYYY那么您的查询将起作用。如果它有所不同,那么您的查询将引发异常或工作但给出不正确的结果。由于NLS_DATE_FORMAT是一个会话参数,并且每个用户都可以将其设置为他们想要的任何值,那么您不应该依赖它来保持一致。

相反,将间隔文字添加到日期(不需要任何与字符串的转换):

TRUNC( src.invoiced_date ) + INTERVAL '3:56:24' HOUR TO SECOND

或者将日期显式转换为正确格式的字符串:

TO_DATE( TO_CHAR( e.invoiced_date, 'MM/DD/YYYY' ) || ' 3:56:24', 'MM/DD/YYYY HH24:MI:SS' )

推荐阅读