Встроенный запрос для обновления нескольких строк - PullRequest
0 голосов
/ 11 августа 2009

Вот краткое описание таблиц, с которыми я работаю в Oracle 10g:

Примечания: Таблица: jnldetail: одна строка с данными, как показано. Существует несколько идентификаторов пакетов, привязанных к одному и тому же bill_ref_no для учетной записи. Поэтому я пытаюсь обновить "jnldetail" с помощью нескольких package_id.

Отношение между index_bill_ref и bill_ref_no: 1 - 1 Отношение между account_no и (index_bill_ref и bill_ref_no): 1 - много

**Table : jnldetail** :
account_no     bill_ref_no     amount

8594822        74282843        822

Я добавляю еще один столбец package_id с помощью следующей команды:

alter table jnldetail add package_id number(10)


**table: bill_invoice**:

account_no    bill_ref_no       index_bill_ref

8594822       74282843          763653495


**table: bill_invoice_detail**:

index_bill_ref      package_id    component_id

763653495           20000077      20000177

763653495           20000250      20000528

763653495           13000019      13000137

**Expected Result:**
**Table : jnldetail** :

account_no     bill_ref_no     amount       package_id

8594822        74282843        822          20000077

8594822        74282843        822          20000250

8594822        74282843        822          13000019 

Мой запрос:

UPDATE jnldetail tp
SET tp.package_id = (
    select 
         t1.package_id 
    from bill_invoice_detail t1
       , bill_invoice t2
    where 
         t1.index_bill_ref = t2.index_bill_ref 
      and
         t2.account_no = tp.account_no
)

Сообщение об ошибке: ora 01427: подзапрос одной строки возвращает более одной строки

Любые входные данные будут полезны.

Спасибо!

Ответы [ 3 ]

1 голос
/ 11 августа 2009

Проблема в том, что вы пытаетесь установить для tp.package_id более одного числа, потому что ваш подзапрос возвращает более одного результата, например, 20000077 и 13000019. Вам нужно изменить подзапрос, чтобы возвращалось только одно значение.

0 голосов
/ 11 августа 2009

Это сложно по двум причинам:

1) вы хотите обновить существующую строку и хотите добавить две новые строки

2) двум новым строкам нужны данные как из исходной таблицы jnldetail (сумма), так и из таблиц bill_invoice (package_id)

Для адреса 1 вы можете использовать оператор MERGE, но из-за 2 в предложении using оператора MERGE необходим jnldetail.

Вот ваш пример:

SQL> create table jnldetail (account_no, bill_ref_no, amount)
  2  as
  3  select 8594822, 74282843, 822 from dual
  4  /

Tabel is aangemaakt.

SQL> alter table jnldetail add package_id number(10)
  2  /

Tabel is gewijzigd.

SQL> create table bill_invoice (account_no, bill_ref_no, index_bill_ref)
  2  as
  3  select 8594822, 74282843, 763653495 from dual
  4  /

Tabel is aangemaakt.

SQL> create table bill_invoice_detail (index_bill_ref, package_id, component_id)
  2  as
  3  select 763653495, 20000077, 20000177 from dual union all
  4  select 763653495, 20000250, 20000528 from dual union all
  5  select 763653495, 13000019, 13000137 from dual
  6  /

Tabel is aangemaakt.

Таблицы, как вы их описали.

SQL> UPDATE jnldetail tp
  2     SET tp.package_id =
  3         ( select t1.package_id
  4             from bill_invoice_detail t1
  5                , bill_invoice t2
  6            where t1.index_bill_ref = t2.index_bill_ref
  7              and t2.account_no = tp.account_no
  8         )
  9  /
       ( select t1.package_id
         *
FOUT in regel 3:
.ORA-01427: single-row subquery returns more than one row

Ваш оператор обновления не выполнен, поскольку вы пытаетесь присвоить результат запроса на 3 строки-возврата одному столбцу.

Вот оператор MERGE:

SQL> merge into jnldetail jd
  2  using ( select bi.account_no
  3               , bi.bill_ref_no
  4               , jd.amount
  5               , bid.package_id
  6               , row_number() over (partition by bi.account_no,bi.bill_ref_no,bi.index_bill_ref order by null) rn
  7            from bill_invoice bi
  8               , bill_invoice_detail bid
  9               , jnldetail jd
 10           where bi.index_bill_ref = bid.index_bill_ref
 11             and bi.account_no = jd.account_no
 12             and bi.bill_ref_no = jd.bill_ref_no
 13        ) bi
 14     on (   jd.account_no     = bi.account_no
 15        and jd.bill_ref_no    = bi.bill_ref_no
 16        and bi.rn             = 1
 17        )
 18   when matched then
 19        update set package_id = package_id
 20   when not matched then
 21        insert values (bi.account_no,bi.bill_ref_no,bi.amount,bi.package_id)
 22  /

3 rijen zijn samengevoegd.

Обратите внимание, что мы выбираем произвольную строку для обновления: ту, у которой rn = 1. Это приводит к желаемому набору результатов:

SQL> select * from jnldetail
  2  /

ACCOUNT_NO BILL_REF_NO     AMOUNT PACKAGE_ID
---------- ----------- ---------- ----------
   8594822    74282843        822   13000019
   8594822    74282843        822   20000077
   8594822    74282843        822   20000250

3 rijen zijn geselecteerd.

С уважением, Роб.

0 голосов
/ 11 августа 2009

Почему бы не разделить таблицы и не использовать объединение, когда вы готовы получить полные данные?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...