Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Oracle Новый топик    Ответить
 Не получается сделать update таблицы, связанной с другой таблицей  [new]
PSergeyA
Member

Откуда: Иркутск
Сообщений: 77
Здравствуйте!
нужно обновить даты в таблице договоров (t_contract). Условия, ограничивающие обновляемые строки и сами даты, на которые нужно заменить, лежат в другой таблице (t_vrem).

update t_contract c set c.datebegin=v.datebegin
from t_vrem v
where c.account=v.account  
and c.dognum=v.dognum
and c.vndr_id=v.vndr_id

т.е. записи, обновляемые в таблице t_contract ограничиваются лицевыми счетами (account), поставщиками (vndr_id) и номерами договоров из таблицы t_vrem, которая вся состоит из этих трёх полей + поле datebegin

прошу помочь!, если кто-нибудь знает ответ, потому что сам я уже довольно долго искал в интернете и то, что нашёл (запрос такого вида, как написал) у меня не работает, а больше ничего подходящего найти не удалось.
У меня стоит Oracle10 или по-моему называется Oracle10i
13 июл 11, 04:12    [10965284]     Ответить | Цитировать Сообщить модератору
 Re: Не получается сделать update таблицы, связанной с другой таблицей  [new]
PSergeyA
Member

Откуда: Иркутск
Сообщений: 77
если переписать этот пример с оператором exists, то так можно (находил здесь по поиску), но сложно поверить, что нельзя просто сделать связь с таблицей, примерно как в select, что в Oracle такого способа нет. Такая большая развитая системма и такого нет..
не верится.
13 июл 11, 06:00    [10965317]     Ответить | Цитировать Сообщить модератору
 Re: Не получается сделать update таблицы, связанной с другой таблицей  [new]
_plus_
Member

Откуда:
Сообщений: 43
PSergeyA,

update t_contract c set c.datebegin=( select v.datebegin
from t_vrem v
where c.account=v.account  
and c.dognum=v.dognum
and c.vndr_id=v.vndr_id)

может так попробовать?

какую ошибку выдает при обновлении?
13 июл 11, 06:00    [10965319]     Ответить | Цитировать Сообщить модератору
 Re: Не получается сделать update таблицы, связанной с другой таблицей  [new]
gav-m
Member

Откуда: прибайкалье
Сообщений: 117
PSergeyA
если переписать этот пример с оператором exists, то так можно (находил здесь по поиску), но сложно поверить, что нельзя просто сделать связь с таблицей, примерно как в select, что в Oracle такого способа нет. Такая большая развитая системма и такого нет..
не верится.

Если не нравится вариант с exists, где то рядом был описан и такой способ:
update 
  (select c.datebegin "DST",
          v.datebegin "SRC"
   from 
     t_contract c,
     t_vrem v
   where 
     c.account=v.account  
   and 
     c.dognum=v.dognum
   and 
     c.vndr_id=v.vndr_id
  )
set dst=src;
Но имеется ряд ограничений.
13 июл 11, 07:52    [10965359]     Ответить | Цитировать Сообщить модератору
 Re: Не получается сделать update таблицы, связанной с другой таблицей  [new]
andreymx
Member

Откуда: Запорожье
Сообщений: 54383
если не подойдет вариант gav-m, то MERGE подойдет
13 июл 11, 08:33    [10965422]     Ответить | Цитировать Сообщить модератору
 Re: Не получается сделать update таблицы, связанной с другой таблицей  [new]
PSergeyA
Member

Откуда: Иркутск
Сообщений: 77
_plus_
т.к. у меня ограничения на объём обновляемых записей в таблице t_contract находятся в таблице t_vrem, то обновляться будут все записи t_contract, но те, которые в подзапросе по условиям совпадут - обновятся как и нужно, а остальные даты станут null.
Т.е., к сожалению, в моём случае не подходит. Если бы огарничение не лежало бы в другой таблице, а задавалось в обновляемой, тогда этот вариант бы был как раз.

gav_m
тоже интересный способ. у меня он сработал. надо будет ещё получше разобраться как он работает. Т.е. так по-моему можно.

andreymx
наверно, надо будет почитать подробнее. я его что-то всё время обходил стороной.

Большое спасибо всем за участие в моей проблеме.

я тут тоже кое что сам смог придумать:

1) способ - подходит для небольших объёмов обновляемых записей, может быть, до нескольких тысяч строк:

сначала сделал выборку для каждой строки t_vrem соответствующего первичного ключа из t_contract обычным select-запросом
потому что в select таблицы можно связать и первичный ключ обновляемой записи можно получить и поставить рядом с датой, на которую нужно заменить.
перв ключь - t_contract.id_contract - добавил его отдельным полем к каждой строке t_vrem - t_vrem.id_contract
тогда можно сделать нужное кол-во операторов update, обновляющих только одну строку с id_contract:

select 'update t_contract set datebegin=to_date('''||to_char(v.datebegin,'dd.mm.yyyy')||''',''dd.mm.yyyy'') where id_contract='||to_char(v.id_contract)||';' 
from t_vrem;

тогда после выполнения этого запроса будет столько update-ов стколько строк в t_vrem, сколько и нужно обновить дат.
Их все списком выполнил.

Способ надёжный, каждый раз вижу, что обновляется одна запись, т.е. нет сомнений, что обновляется то что надо, потом проверил и всё.

2) второй подошёл тоже , но для меня он немного рискованный, т.к. не знаю точно не вижу что обновляется, всё делается скрыто в цикле. но для больших объёмов наверно он лучше подходит.

declare 
  cursor C is
  select v.account, v.dognum, v.vndr_id, v.datebegin from t_vrem;
begin
  for F in C loop
    update t_contract set datebegin=F.datebegin where account=F.account and dognum=F.dognum and vndr_id=F.vndr_id;
  end loop;
end;

спасибо за помощь!
14 июл 11, 09:36    [10971314]     Ответить | Цитировать Сообщить модератору
Все форумы / Oracle Ответить