Обновить поле даты одной таблицы из значения, взятого из другой таблицы - PullRequest
0 голосов
/ 20 декабря 2018

У меня есть две таблицы A и B, где у обоих есть поля даты, но в другом формате («ММ / ДД / ГГГГ ЧЧ: MI: СС» и «ММ / ДД / ГГГГ»), и у них обоих есть общее поле invoiced_value,Мне нужно обновить значения даты таблицы A (с «ММ / ДД / ГГГГ ЧЧ: МИ: СС») из значений таблицы B (с «ММ / ДД / ГГГГ»).Могу ли я использовать следующий запрос?Могу ли я добавить дату к этой дате (e.invoiced_date || '3:56:24', 'ММ / ДД / ГГГГ ЧЧ: МИ: СС')?.

  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

1 Ответ

0 голосов
/ 20 декабря 2018

[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 будет неявно преобразован из 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' )
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...