Oracle SQL Оператор обновления со значением, созданным в подзапросе - PullRequest
0 голосов
/ 14 января 2020

Я пытаюсь написать оператор обновления для вставки значения, которое вычисляется в подзапросе, и имеет ограниченный успех.

Утверждение, которое я до сих пор пробовал:

update intuit.men_doc doc1
set doc1.doc_udf5 = (select
substr(doc.doc_dtyc, instr(doc.doc_dtyc, 'GAPP-', 2)+5 )||'_'||row_number() over(partition by 
doc.doc_dtyc order by doc.doc_cret) docDeleteId
from
intuit.men_doc doc 
where
doc.doc_dtyc != 'DM-GAPP-SFUL'
and doc.doc_dtyc like 'DM-GAPP%'
and doc.doc_cred >= '01/Oct/2017' and doc.doc_cred < '01/Oct/2018'
and doc1.doc_code = doc.doc_code
)

Это приводит к следующему сообщению об ошибке

ERROR: Error 1427 was encountered whilst running the SQL command. (-3)
Error -3 running SQL : ORA-01427: single-row subquery returns more than one row

У меня нет большого опыта работы с операторами UPDATE, поэтому любой совет о том, как я могу переписать это, чтобы я мог обновить несколько тысяч записей одновременно, был бы приветствуется.

РЕДАКТИРОВАТЬ: Добавление данных примера

Пример данных:

MEN_DOC
DOC_CODE    DOC_DTYC    DOC_UDF5    DOC_CRED
123456A     CV                      08/Nov/2017
456789B     CV                      11/Jan/2018
789123C     CV                      15/Feb/2018
123987B     TRAN                    01/Dec/2017             

Как я хочу, чтобы данные выглядели после запуска скрипта

MEN_DOC
DOC_CODE    DOC_DTYC    DOC_UDF5    DOC_CRED
123456A     CV          CV_1        08/Nov/2017
456789B     CV          CV_2        11/Jan/2018
789123C     CV          CV_3        15/Feb/2018
123987B     TRAN        TRAN_1      01/Dec/2017  

Спасибо

Ответы [ 2 ]

0 голосов
/ 15 января 2020

Вы можете использовать select в качестве исходной таблицы в merge, как здесь:

merge into men_doc tgt
using (select doc_code, 
              doc_dtyc||'_'||row_number() over (partition by doc_dtyc order by doc_cred) as calc
         from men_doc) src
on (tgt.doc_code = src.doc_code)
when matched then update set tgt.doc_udf5 = src.calc;

dbfiddle

Я предположил, что doc_code уникален.

0 голосов
/ 14 января 2020

Вы используете row_number(), что предполагает, что вы ожидаете, что подзапрос вернет более одной строки. Неравенство на doc_code поддерживает эту интерпретацию.

Просто измените row_number() на count(*), чтобы у вас была агрегация, которая всегда будет возвращать одну строку и получать желаемый последовательный счет:

update intuit.men_doc doc1
    set doc1.doc_udf5 = (select substr(doc.doc_dtyc, instr(doc.doc_dtyc, 'GAPP-', 2)+5 ) ||'_'|| count(*) docDeleteId
                         from intuit.men_doc doc 
                         where doc.doc_dtyc <> 'DM-GAPP-SFUL' and
                               doc.doc_dtyc like 'DM-GAPP%' and
                               doc.doc_cred >= date '2017-10-01' and
                               doc.doc_cred < date '2018-10-01' and
                               doc1.doc_code = doc.doc_code
                         );
...