Хотя могут быть способы обновления таблицы другой таблицей с помощью причудливых подвыборов, я считаю, что лучший подход - написать программу для этого с использованием API SQL (будь то DBI с драйвером DBD :: DB2 для perl JDBC для Java или библиотеки C и т. Д.) Для выполнения SELECT, извлечения каждой строки результата из RESULTSET с помощью курсора и обновления.
PSEUDOCODE (я не знаю, на каком языке вы знакомы):
dbHandle = sqllib->open_connection(database, user, password)
select_statement = dbHandle->prepare('SELECT id FROM idstoupdate')
update_statement = dbHandle->prepare('UPDATE clients SET col1=?, col2=? WHERE ID=?')
resultset = statement->execute(select_statement)
foreach (row in resultset) {
id = row.getColumn('id')
update_statement->execute('1','2',id)
}
dbHandle->disconnect();
Вы хотите добавить проверку ошибок. Если вы хотите, чтобы все обновления были применены, или ни одного, то вы должны изучить начало транзакции и фиксацию всей транзакции, если у вас нет ошибок. В DB2 Infocenter .
содержится множество материалов о том, как сделать все это.
Примечание:
Если ваши исходные данные для idstoupdate
- это файл, то вы можете пропустить оператор select и ту работу, которую вы делаете, чтобы загрузить таблицу idstoupdate
, и просто прочитать файл и обновить базу данных. Это был бы наиболее эффективный способ обработки обновлений таблицы.
Если вам просто нужно обновить таблицу из другой таблицы с использованием чистого SQL, то наиболее распространенными примерами являются следующие:
UPDATE table1 t1
SET (t1.field1, t1.field2) =
(
SELECT t2.field1,
t2.field2
FROM table2 t2
WHERE t1.joinfield = t2.joinfield
AND t2.criteriafield = 'qualifier'
)
WHERE EXISTS
(
SELECT 1
FROM table2
WHERE t1.joinfield = table2.joinfield
AND t2.criteriafield = 'qualifier'
)
, который исключает предикат IN
, но, вероятно, не намного эффективнее с точки зрения памяти или пространства журналов, и поскольку он не так прост, как выборка, цикл, выборка, обновление, вы должны быть уверены, что все критерии верны. Ваш случай немного проще - я думаю, что это сработает, но мне нужен экземпляр db2, чтобы попробовать его:
UPDATE clients t1
SET t1.col1 = '1', col2 = 'y'
WHERE EXISTS
(
SELECT 1
FROM idstoupdate t2
WHERE t1.id = t2.id
)
Edit:
Я на самом деле удивлен, что запрос, который вы дали, не работал с SQL-белка, так как это допустимый запрос. Он может даже работать аналогично примеру, который я привел, поскольку DB2 очень хороша в оптимизации SQL / определении наилучшего пути доступа.
В своем ответе я пытался показать наиболее эффективный для памяти способ обновления таблицы, а также общий шаблон обновления строк в одной таблице из другой таблицы с использованием чистого SQL (который охватывал бы случаи, когда одна таблица содержит больше чем только строки, которые вы хотите обновить).
Кроме того, я с подозрением отношусь к предикатам IN, которые содержат более 20 или около того значений, даже если современные движки баз данных обрабатывают их с легкостью.
Однако лучший способ проверить, эффективно ли обработчик ваших запросов обрабатывает ядро базы данных и / или сравнить два запроса SQL, - это использовать команды объяснение SQL .