Реализация SQL Server 2005 MySQL REPLACE INTO?
MySQL имеет это невероятно полезно, но properitary REPLACE INTO
команда SQL.
можно ли легко эмулировать это в SQL Server 2005?
запуск новой транзакции, выполнение Select()
и затем UPDATE
или INSERT
и COMMIT
всегда немного больно, особенно при выполнении этого в приложении и, следовательно, всегда сохраняя 2 версии заявления.
интересно, есть ли легкий и универсальная способ реализации такой функция в SQL Server 2005?
4 ответа:
это то, что раздражает меня о MSSQL (разглагольствовать на мой блог). Я желаю MSSQL поддерживается
upsert
.@Dillie-o's код является хорошим способом в старых версиях SQL (+1 голос), но это все еще в основном две операции ввода-вывода (
exists
а тоupdate
илиinsert
)есть немного лучший способэтот пост, фактически:
--try an update update tablename set field1 = 'new value', field2 = 'different value', ... where idfield = 7 --insert if failed if @@rowcount = 0 and @@error = 0 insert into tablename ( idfield, field1, field2, ... ) values ( 7, 'value one', 'another value', ... )
это уменьшает его до одной операции ввода-вывода, если это обновление, или два, если вставка.
MS Sql2008 вводит
merge
из стандарта SQL:2003:merge tablename as target using (values ('new value', 'different value')) as source (field1, field2) on target.idfield = 7 when matched then update set field1 = source.field1, field2 = source.field2, ... when not matched then insert ( idfield, field1, field2, ... ) values ( 7, source.field1, source.field2, ... )
теперь это действительно только одна операция ввода-вывода, но ужасный код : - (
функциональность, которую вы ищете, традиционно называется UPSERT. По крайней мере зная, что это называется может помочь вам найти то, что вы ищете.
Я не думаю, что SQL Server 2005 имеет какие-либо отличные способы сделать это. 2008 вводит оператор MERGE, который может использоваться для выполнения этого, как показано в:http://www.databasejournal.com/features/mssql/article.php/3739131 или http://blogs.conchango.com/davidportas/archive/2007/11/14/SQL-Server-2008-MERGE.aspx
слияние было доступно в бета-версии 2005 года, но они удалили его в финальной версии.
то, что делает upsert/merge, является чем-то вроде эффекта...
IF EXISTS (SELECT * FROM [Table] WHERE Id = X) UPDATE [Table] SET... ELSE INSERT INTO [Table]
Так что, надеюсь, сочетание этих статей и этот псевдо-код может заставить вещи двигаться.
Я написал пост в блоге об этой проблеме.
суть в том, что если вы хотите дешевый обновления ... и вы хотите быть в безопасности для одновременного использования. попробуйте:
update t set hitCount = hitCount + 1 where pk = @id if @@rowcount < 1 begin begin tran update t with (serializable) set hitCount = hitCount + 1 where pk = @id if @@rowcount = 0 begin insert t (pk, hitCount) values (@id,1) end commit tran end
таким образом, у вас есть 1 операция для обновлений и максимум 3 операции для вставок. так что, если вы обычно обновляете это безопасный дешевый вариант.
Я также был бы очень осторожен, чтобы не использовать ничего, что небезопасно для одновременного использования. Его очень легко получить первичный ключ нарушения или дублирование строк в производстве.