2016-11-26 2 views
1

У меня сейчас проблема, и я бы хотел, чтобы это было быстро.INSERT INTO или UPDATE в случае состояния

Я уже нашел другие ответы по этому вопросу, но никто не помог, я прочитал о INSERT INTO и INSERT ON DUPLICATE KEY UPDATE, но я думаю, что это действительно не помогает мне.

Итак, у меня есть некоторые Migrations enabled, которые добавляют новые столбцы в существующие таблицы, дело в том, что существующие записи в таблице до миграции получают записи с пустыми значениями даже в существующих столбцах (потому что я меняю порядок столбцов на новой таблице мигрировал)

Я делаю SP, цель которого - заполнить новую таблицу, перенесенную в соответствии с вставками или обновлениями.

  • Я хочу, чтобы вставить новые записи всегда за исключением случая, что я нашел существующую запись на столе с пустыми столбцами (Id колонки - первичный ключ - заполняется)

«псевдо-код» (смешивание SQL таблиц знаний и C# синтаксис) будет что-то вроде этого:

int i = 0; 
foreach(Record item in importing_data_table) 
{ 

    if(i < tableMigrated.Length && tableMigrated[i].Column IS NULL) 
    { 
      UPDATE tableMigrated[i] SET Column = item.Column 
    } 
    else 
    { 
      INSERT INTO item 
    } 

    i++; 
} 

Примечание: Удаление всех строк от tableMigrated до того вставка не возможно, потому что есть внешние ключи к этому столу. Я получил следующую ошибку, пытающуюся использовать такой подход: - Оператор DELETE противоречил ограничению REFERENCE «FK_blabla.Testing_testingTest.tableMigrated_Id».

NOTE2: Может быть, мой единственный вариант - использовать курсоры?

Большое вам спасибо за вашу помощь заранее!

+1

я знал, что кто-то собирался задать этот вопрос. Я решил это для себя на этой неделе. Update возвращает целое число, указывающее количество затронутых строк. Поэтому, если Update возвращает ноль, тогда я вставляю данные. Вы не можете вставить, если значение основного ключа уже существует в базе данных. Поэтому сначала попробуйте обновить, и если он вернет нулевые строки, то используйте Insert. – jdweng

ответ

1

В вашей хранимой процедуре используйте заявление о слиянии. Merge предоставляет функциональность INSERT на основе вашего условия вставки, в противном случае UPDATE. Вот пример

MERGE dbo.FactBuyingHabits AS Target 
USING (SELECT CustomerID, ProductID, PurchaseDate FROM dbo.Purchases) AS Source 
ON (Target.ProductID = Source.ProductID AND Target.CustomerID = Source.CustomerID) 
WHEN MATCHED THEN 
    UPDATE SET Target.LastPurchaseDate = Source.PurchaseDate 
WHEN NOT MATCHED BY TARGET THEN 
    INSERT (CustomerID, ProductID, LastPurchaseDate) 
    VALUES (Source.CustomerID, Source.ProductID, Source.PurchaseDate) 

Посмотрите на Technet - Inserting, Updating, and Deleting Data by Using MERGE

+0

Спасибо за ваш ответ, я получаю сообщение об ошибке, не могу найти проблему, иногда SQL просто сводит меня с ума, черт возьми, это ... ошибка, показанная в большинстве случаев, совсем не помогает! Вот мой текущий код, http://pastebin.com/R0uByLqv – TiagoM

+0

Finnaly получил его работу, кажется, мне действительно нужно использовать «Target» в качестве последнего слова в заявлении Merge (первая строка), я жестко, что это может быть любой Псевдоним для целевой базы данных, кажется, теперь =/ – TiagoM

+0

Фактически я могу использовать слово «Target» с любым псевдонимом для таблицы, моя проблема заключалась в замене всего, что также изменилось «КОГДА НЕ СООТВЕТСТВУЕТ ЦЕЛЕВЫМ ТОГДА» на «КОГДА НЕ СООТВЕТСТВУЕТ» BY MYTABLEALIAS THEN ", изменив MYTABLEALIAS на TARGET, он начал работать отлично, большое вам спасибо за ваш ответ! :) – TiagoM

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