Обновление нескольких строк в SQL Server 2005 (версия 9.0.5000)

#sql #sql-server-2005

#sql #sql-server-2005

Вопрос:

В настоящее время я автоматически создаю скрипт с помощью программы, которая копирует файлы из одного места в другое, и раньше я делал следующее:

 UPDATE d
SET Path = t.Path
FROM dbo.tableOperation d
JOIN (VALUES (1, 'Path 1'),
             (2, 'Path 2')) t (IdRegister, Path) ON t.IdRegister = d.IdRegister
  

И на SQL Server 2008 R2 (v10.50.1600) все работало нормально, но я обнаружил некоторые проблемы с синтаксисом при попытке отобразить предполагаемый план выполнения скрипта на сервере, я должен обновить данные (9.0.50000). В ошибке конкретно указано

Неправильный синтаксис рядом с ключевым словом ‘VALUES’

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

Ответ №1:

Возможно, вам придется переключиться с VALUES() на UNION ALL для 2005 (также будет работать в 2008). Но имейте в виду, что поддержка SQL Server 2005 закончилась несколько лет назад. (Я имею в виду, это настолько старое, что я забыл VALUES() , что его там не было.) Время двигаться дальше?

 UPDATE d
SET Path = t.Path
FROM dbo.tableOperation AS d
INNER JOIN 
(
    SELECT 1,'Path 1'
    UNION ALL SELECT 2,'Path 2'
) AS t (IdRegister, Path) 
ON t.IdRegister = d.IdRegister;
  

Комментарии:

1. Я бы с удовольствием обновил его, но на самом деле это не мой вызов.

2. Я провел тест с немногим более 27 тыс. строк, и для отображения предполагаемого плана выполнения требуется много времени, как вы думаете, могу ли я каким-либо образом оптимизировать код?

3. @Throkar Может быть, не пытайтесь обновлять 27 тысяч строк одновременно, используя любой подход? Я бы сказал, что 10 КБ за раз, вероятно, здесь приличная верхняя граница, может быть, даже меньше.

4. … и либо вам нужно обновить тысячи и тысячи строк, либо вы этого не делаете. если вы собираетесь выбрать подход, основанный на относительных оценочных планах выполнения, прекратите делать это, присоединившись к списку из 27 тыс. постоянных значений и поместите их в таблицу. Затем вы можете размещать ключи, добавлять индексы, извлекать выгоду из статистики и т. Д.

5. Ну, в основном, что я делаю, это использую программу, которую я создал, для копирования файлов с одного NAS на другой, и мне нужно обновить регистры, связанные с этими файлами в базе данных, и вставить новые регистры, которые имеют определенные требования, в другую базу данных, для этого я создаю сценарии в кодедля запуска отдельно, поэтому я попытался сделать этот скрипт для масштабного обновления всякий раз, когда я заканчиваю копирование файлов.

Ответ №2:

Добрый день, Трокар,

Предполагая, что я понял ваши потребности (в чем я не совсем уверен), и поскольку вы используете значения с жестким кодом (VALUES (1, 'Path 1'), (2, 'Path 2')) , тогда, возможно, простое прямое обновление может решить ваши потребности

Поскольку вы не предоставили DDL DML, я буду использовать базовую демонстрацию

 -- Let's assume that this our DDL DML
drop table if exists tableOperation
GO
CREATE TABLE tableOperation(IdRegister int, Path varchar(100))
INSERT tableOperation(IdRegister) values (2),(4),(5)
select * from tableOperation
GO

--UPDATE d
--SET Path = t.Path
--FROM dbo.tableOperation d
--JOIN (VALUES (1, 'Path 1'),(2, 'Path 2')) t (IdRegister, Path) 
--  ON t.IdRegister = d.IdRegist

-- You can use this query
UPDATE dbo.tableOperation
SET Path = CASE   
    WHEN IdRegister = 1 then 'Path 1'
    WHEN IdRegister = 2 then 'Path 2'
END
WHERE IdRegister in (1,2)
  

В фильтре (условие WHERE) Я использую жестко запрограммированный список всех значений, которые вы использовали в условии ON, а в разделе SET я просто использую оператор CASE с жестким кодом условий

Может ли этот подход удовлетворить ваши потребности?