#sql #sql-server #tsql
Вопрос:
У меня есть таблица под названием Customers
, которая содержит несколько столбцов, таких как FirstName
, LastName
, DateFileOpened
OrderedInLastMonth
, и т. Д… В каждой строке более 20 столбцов, а всего около 500 строк.
Каждый час у меня есть механизм, который удаляет другой источник этих данных для обновленных записей клиентов и помещает их во временную таблицу, которую затем необходимо скопировать в мою основную таблицу. Customers
Однако любой или все столбцы в любой или всех новых строках могут отличаться от существующих Customers
.
В настоящее время, и чтобы избежать создания почти повторяющихся записей, мой довольно дерьмовый код делает , например, a delete from [Customers] where CoOrigin = 'England'
, прежде чем импортировать новые, чтобы занять их место. Однако у меня есть другие запросы, которые необходимо выполнить примерно в то же время, что и этот, и часто это мешает, в результате чего эти другие запросы возвращают 0 данных, потому что записи клиентов, которые могут быть возвращены, отсутствуют благодаря команде delete.
Еще раз, я понимаю, что это ужасное кодирование, но я все еще совсем новичок. Я просмотрел инструкции update / replace, но, похоже, им нужно указать, какие столбцы в каждой строке нуждаются в обновлении, но это может быть любой из 20 . Я знаю, что это позволило бы выполнить задачу, но это похоже на более плохой код. Я также не уверен, как ссылаться на временную таблицу, в которую импортируются новые записи, прежде чем они будут скопированы в основную Customers
таблицу (и временная таблица будет удалена).
Любая помощь или указания, которые вы можете мне дать, будут мне очень признательны. Спасибо.
Комментарии:
1. Могут ли строки быть записаны для обновления каким-либо другим процессом или они обновляются только в процессе обновления?
2. @Поддерживается только процессом обновления, который происходит каждый час. В противном случае их не трогают.
3. в результате эти другие запросы возвращают 0 данных .Это должно быть невозможно, если ваш процесс обновления находится в транзакции, и в процессе запроса не используется никакой «хитрости»блокировки. Покажите какой-нибудь код. И да, 500 строк тривиальны и должны быть примерно мгновенными для обновления.
4. Похоже, вам просто не хватает транзакционного элемента в вашей обработке. Покажите свой код для получения дополнительной помощи.
5. Должен быть какой-то способ соотнести, какие клиенты являются новыми, а какие нуждаются в обновлении. Как бы вы это сделали, есть ли
ID
колонка? Примеры данных и ожидаемый результат очень помогут, наряду с вашим существующим кодом. Похоже, вам просто нужноMERGE
заявление
Ответ №1:
Вы имеете дело с микроскопическим объемом данных, поэтому вы можете использовать подход «большого молотка» для обновления каждого клиента, не влияя на другие процессы.
begin;
lock table customer in exclusive mode;
delete from customer;
insert into customer select from temp_customer;
commit;
Процессы, которым необходим доступ к таблице клиентов, просто заблокируются до завершения обновления (максимум через пару секунд), а затем продолжатся без изменений.