Использование ROWID
Поскольку вы можете использовать ROWID
, это будет идеальный способ сделать это.И в зависимости от версии Oracle ограничение длины запроса может быть достаточно большим для запроса с таким количеством элементов в предложении IN
.Проблема заключается в количестве элементов в списке выражений IN
- ограничено 1000 .
Так что вам придется разбить список RowIDв наборы по 1000 за раз или удалите только одну строку за раз;с или без executemany()
.
>>> len(delrows) # rowids to delete
5000
>>> q = 'DELETE FROM sometable WHERE ROWID IN (' + ', '.join(f"'{row}'" for row in delrows) + ')'
>>> len(q) # length of the query
55037
>>> # let's try with just the first 1000 id's and no extra spaces
... q = 'DELETE FROM sometable WHERE ROWID IN (' + ','.join(f"'{row}'" for row in delrows[:1000]) + ')'
>>> len(q)
10038
Возможно, вы находитесь в пределах длины запроса и можете даже сохранить некоторые символы с минимальным разделителем элементов ','
.
Без ROWID
Без первичного ключа или ROWID единственный способ идентифицировать каждую строку состоит в том, чтобы указать все столбцы в предложении WHERE и сделать много строк за один раз, их необходимо объединить в OR:
DELETE FROM sometable
WHERE ( col1 = 'val1'
AND col2 = 'val2'
AND col3 = 'val3' ) -- row 1
OR ( col1 = 'other2'
AND col2 = 'value2'
AND col3 = 'val3' ) -- row 2
OR ( ... ) -- etc
Как видите, это не самый хороший запрос для создания, но он позволяет вам делать это без ROWID.
И в обоих случаях вам, вероятно, не нужноиспользование параметризованных запросов, поскольку список IN
в 1 или OR
, группировка в 2 является переменной.(Да, вы могли бы создать его параметризованный после построения всего расширенного SQL с тысячами параметров. Не уверен, каков этот предел.) Способ executemany()
определенно проще писать и делать, но для скорости - одиночные большие запросы (любой из вышеперечисленных двух), вероятно, превзойдет executemany с тысячами элементов.