Преобразование динамического курсора SQL Server в Oracle - PullRequest
0 голосов
/ 25 апреля 2018

У меня есть таблица, содержащая результат совпадения строк в двух разных таблицах. В таблице строки однозначно идентифицируются по столбцу export_invoice_id, а в таблице b записи однозначно идентифицируются по столбцу import_invoice_id. В дополнение к этим идентифицирующим столбцам обе таблицы имеют набор столбцов, содержащих данные заголовка счета. Мне нужно сопоставить строки из этих двух таблиц

Существует задание, которое проходит через записи в таблицах a и b и создает оценку совпадения в зависимости от того, насколько хорошо любая строка данных в таблице a соответствует любой строке данных в таблице b. Результат сохраняется в таблицах совпадений. Таблица содержит export_invoice_id из таблицы a, import_invoice_id из таблицы b и match_score, указывающие, насколько равны записи. Чем выше match_score - тем более равны записи в двух таблицах.

Пример данных в таблице соответствий:

IMPORT_INVOICE_ID    EXPORT_INVOICE_ID    MATCH_SCORE    SORT_ID
0                        5117095              17            1
0                        5117096               9            2
0                        5117097               9            3
1                        5117096              17            4
1                        5117097              17            5
1                        5117095               9            6
2                        5117097              17            7
2                        5117096              10            8
2                        5117095               9            9

Столбец sort_id задает порядок сортировки (SORT BY import_invoice_id, match_score DESC, export_invoice_id)

Я хочу удалить строки из этой таблицы соответствий, чтобы у меня остались только лучшие совпадения идентификатора export_invoice в таблице a с import_invoice_id в таблице b. Каждое значение import_invoice_id и export_invoice_id может использоваться только один раз.

IMPORT_INVOICE_ID    EXPORT_INVOICE_ID    MATCH_SCORE    SORT_ID
0                        5117095              17            1
1                        5117096              17            4
2                        5117097              17            7

Чтобы сделать это в SQL Server, у меня есть следующий курсор, который делает то, что я хочу (обратите внимание на ДИНАМИКУ КУРСОРА):

DECLARE @ExportInvoiceId AS int;
DECLARE @ImportInvoiceID AS int;
DECLARE @SortId AS bigint; 
DECLARE Match_Cursor CURSOR DYNAMIC TYPE_WARNING FOR 
SELECT export_invoice_id, import_invoice_id, sort_id FROM matches ORDER BY sort_id
OPEN Match_Cursor
FETCH NEXT FROM Match_Cursor INTO @ExportInvoiceId, @ImportInvoiceID, @SortId;
WHILE @@FETCH_STATUS = 0 
    BEGIN 
        DELETE FROM matches WHERE sort_id > @SortId AND(export_invoice_id = @ExportInvoiceId OR import_invoice_id = @ImportInvoiceId)
        FETCH NEXT FROM Match_Cursor INTO @ExportInvoiceId, @ImportInvoiceID, @SortId; 
    END; 
CLOSE Match_Cursor; 
DEALLOCATE Match_Cursor; 

Как это можно сделать в Oracle?

1 Ответ

0 голосов
/ 25 апреля 2018

Святая корова, которая была тяжелее, чем я думал

Проблема в том, что oracle действительно читает последовательность иначе, чем sql server

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

так - попробуйте это, это просто прямое удаление, без курсора

 delete
 from matches a
 where (a.match_score,a.sort_id) not in (select max(b.match_score), min(sort_id)
                        from matches b
                        where (a.import_invoice_id=b.import_invoice_id
                        or a.export_invoice_id=b.import_invoice_id))
...