2014-11-17 4 views
2

У меня есть таблица с именем tableFrom, которую нужно вставить в таблицу с именем tableTo. Вставка работала хорошо, но если я снова вставляю те же значения, у меня есть повторяющаяся ошибка ключа. Поэтому я хочу обновить только существующие строки. Я знаю команду ON DUPLICATE с MySQL, к сожалению, отсутствующую в SQL Server.Если существует UPDATE else INSERT для каждой строки таблицы

Если я хочу проверить только для одной только точной строки, легко:

IF EXISTS PK = @PK 

Но я пытаюсь это сделать для всей таблицы, и я не знаю, если это возможно. Я думал о том, что каждый ряд с курсором, я новичок в SQL.

Вот что я придумал:

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE 
BEGIN TRANSACTION 
IF EXISTS (
      SELECT 
       1 
      FROM 
       tableFrom F, 
       tableTo T 
      WHERE 
       T.product = F._product 
      ) 
    BEGIN 
     UPDATE 
      tableTo 
     SET 
      T.something = F.something 
     FROM 
      tableTo T 
       INNER JOIN 
        tableFrom F 
       ON 
        T.product = F._product 
    END 
ELSE 
    BEGIN 
     INSERT INTO tableTo 
      (product, 
      something) 
     SELECT 
      F._product, 
      F.something 
     FROM 
      tableFrom F 
    END 
COMMIT TRANSACTION 

Оператор UPDATE часть работает нормально, но не ВСТАВИТЬ не сделано.

EDIT1:

Попробовал этот код:

MERGE tableTo AS T 
USING tableFrom AS S 
    ON (T.product= S._product) 
WHEN NOT MATCHED BY TARGET 
    THEN INSERT(product, something) VALUES(S._product, S.something) 
WHEN MATCHED 
    THEN UPDATE SET T.Something= S.Something 

Есть следующее сообщение об ошибке: «Неправильный синтаксис около„MERGE“Вы, возможно, потребуется установить уровень совместимости текущей базы данных на более высокое значение. для включения этой функции. См. справку для опции SET COMPATIBILITY_LEVEL для ALTER DATABASE. "

EDIT2:

Я гугле выше сообщение об ошибке, и оказалось, что из-за отсутствующей запятой в конце последней строки перед утверждением MERGE. Команда MERGE работает отлично!

ответ

3

Это не хватает. SQL Server реализует оператор standardMERGE, который позволяет указать, что происходит, когда происходит совпадение или нет между источником и целью. Проверьте примеры documentation.

Соответствия выполняются с использованием условия, которое может содержать много столбцов. MERGE позволяет выполнить INSERT, UPDATE или DELETE в следующих случаях:

  • Матч найден исходя из условия
  • Совпадение происходит только в источнике
  • Совпадение происходит только в мишени

Таким образом, вы можете обновлять существующие строки, вставлять строки, которые существуют только в источнике, удалять строки, которые отображаются только в целевом объекте.

В вашем случае, вы могли бы сделать что-то вроде:

MERGE tableTo AS T 
USING tableFrom AS S 
     ON (T.product= S._product) 
WHEN NOT MATCHED BY TARGET 
    THEN INSERT(product, something) VALUES(S._product, S.something) 
WHEN MATCHED 
    THEN UPDATE SET T.Something= S.Something 
OUTPUT $action, Inserted.*, Deleted.*; 

Это заявление будет вставить или обновить строки по мере необходимости и возвращать значения, которые были вставлены или переписаны с пунктом OUTPUT.

+0

Я попытался MERGE, но SQL Manager сказал мне, что моя таблицаFrom не может быть объединена. Однако эта таблица не создавалась, и, как я уже сказал, я новичок в SQL. –

+0

Вы не можете написать оператор, который использует таблицу, если эта таблица не существует. –

+0

Спасибо за заявление MERGE. Я уже пробовал, но безуспешно. См. Мой отредактированный пост. –

4

Используйте операцию Merge.

От MSDN documentation:

Performs insert, update, or delete operations on a target table based on the results of a join with a source table. For example, you can synchronize two tables by inserting, updating, or deleting rows in one table based on differences found in the other table.

+0

Я пробовал MERGE, но SQL Manager сказал мне, что моя таблицаFrom не может быть объединена. Однако эта таблица не создавалась, и, как я уже сказал, я новичок в SQL. –

+0

Можете ли вы поделиться заявлением MERGE, которое вы попробовали, и сообщением об ошибке? –

+0

Отредактировано мое первое сообщение. –

Смежные вопросы