سؤال

الخلية لديه هذه مفيدة بشكل لا يصدق حتى الآن properitary REPLACE INTO الأمر SQL.

وهذا يمكن بسهولة أن يحتذى به في SQL Server 2005?

بدء معاملة جديدة ، والقيام Select() ثم إما UPDATE أو INSERT و COMMIT هو دائما قليلا من الألم, خاصة عندما يفعل ذلك في تطبيق ولذلك دائما الحفاظ على 2 إصدارات من البيان.

وأتساءل عما إذا كان هناك وسيلة سهلة ، العالمي طريقة لتنفيذ هذه الوظيفة في SQL Server 2005?

هل كانت مفيدة؟

المحلول

هذا هو الشيء الذي يزعجني حول MSSQL (خرف على بلدي بلوق).أتمنى MSSQL دعم upsert.

@Dillie-O رمز هو وسيلة جيدة في السن إصدارات SQL (+1 تصويت), لكنه لا يزال هو الأساس الثاني IO للعمليات ( 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', ... )

هذا يقلل إلى واحد IO العمليات إذا كان التحديث أو اثنين إذا كان إدراج.

MS Sql2008 يدخل merge من SQL:2003 standard:

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, ... )

الآن انها حقا واحدة فقط IO العملية ، ولكن فظيعة code :-(

نصائح أخرى

وظيفة كنت تبحث عن تقليديا يسمى UPSERT.على الأقل معرفة ما يطلق عليه قد تساعدك على العثور على ما كنت تبحث عنه.

لا أعتقد SQL Server 2005 أي طرق للقيام بذلك.2008 يدخل دمج البيان التي يمكن استخدامها لتحقيق ذلك كما هو مبين في: 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/دمج يفعل هو شيئا تأثير...

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 عمليات إدراج.لذا ، إذا كنت عموما تحديث هذه هي آمنة رخيصة الخيار.

وأود أيضا أن تكون حذرا جدا عدم استخدام أي شيء غير آمنة الاستخدام المتزامن.حقا من السهل الحصول على المفتاح الأساسي انتهاكات أو الصفوف المكررة في الإنتاج.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top