Sqlserver
 sql >> Teknologi Basis Data >  >> RDS >> Sqlserver

Bagaimana cara menerapkan prosedur tersimpan Upsert bersyarat?

Saya menyatukan skrip berikut untuk membuktikan trik yang saya gunakan di tahun-tahun sebelumnya. Jika Anda menggunakannya, Anda harus memodifikasinya agar sesuai dengan tujuan Anda. Komentar menyusul:

/*
CREATE TABLE Item
 (
   Title      varchar(255)  not null
  ,Teaser     varchar(255)  not null
  ,ContentId  varchar(30)  not null
  ,RowLocked  bit  not null
)


UPDATE item
 set RowLocked = 1
 where ContentId = 'Test01'

*/


DECLARE
  @Check varchar(30)
 ,@pContentID varchar(30)
 ,@pTitle varchar(255)
 ,@pTeaser varchar(255)

set @pContentID = 'Test01'
set @pTitle     = 'TestingTitle'
set @pTeaser    = 'TestingTeasier'

set @check = null

UPDATE dbo.Item
 set
   @Check = ContentId
  ,Title  = @pTitle
  ,Teaser = @pTeaser
 where ContentID = @pContentID
  and RowLocked = 0

print isnull(@check, '<check is null>')

IF @Check is null
    INSERT dbo.Item (ContentID, Title, Teaser, RowLocked)
     values (@pContentID, @pTitle, @pTeaser, 0)

select * from Item

Triknya di sini adalah Anda dapat menetapkan nilai dalam variabel lokal dalam pernyataan Update. Di atas, nilai "bendera" akan disetel hanya jika pembaruan berfungsi (yaitu, kriteria pembaruan terpenuhi); jika tidak, itu tidak akan berubah (di sini, dibiarkan nol), Anda dapat memeriksanya, dan memprosesnya.

Untuk transaksi dan membuatnya serial, saya ingin tahu lebih banyak tentang apa yang harus dienkapsulasi dalam transaksi sebelum menyarankan bagaimana untuk melanjutkan.

-- Tambahan, tindak lanjut dari komentar kedua di bawah ------------

Ide Mr. Saffron adalah cara yang menyeluruh dan solid untuk menerapkan rutinitas ini karena kunci utama Anda ditentukan di luar dan diteruskan ke database (yaitu Anda tidak menggunakan kolom identitas--baiklah menurut saya, mereka sering digunakan secara berlebihan).

Saya melakukan beberapa pengujian lagi (menambahkan batasan kunci utama pada kolom ContentId, membungkus UPDATE dan INSERT dalam sebuah transaksi, menambahkan petunjuk serializable ke pembaruan) dan ya, itu akan melakukan semua yang Anda inginkan. Pembaruan yang gagal menampar kunci rentang pada bagian indeks itu, dan itu akan memblokir setiap upaya simultan untuk memasukkan nilai baru itu di kolom. Tentu saja, jika N permintaan diajukan secara bersamaan, "pertama" akan membuat baris, dan akan segera diperbarui oleh yang kedua, ketiga, dst.--kecuali jika Anda menyetel "kunci" di suatu tempat di sepanjang baris. Trik yang bagus!

(Perhatikan bahwa tanpa indeks pada kolom kunci, Anda akan mengunci seluruh tabel. Juga, kunci rentang dapat mengunci baris di "kedua sisi" dari nilai baru--atau mungkin tidak, saya tidak uji yang itu. Seharusnya tidak masalah, karena durasi operasi harus [?] dalam milidetik satu digit.)



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Apakah ada perbedaan antara SQL Server Express (2012) dan LocalDB?

  2. Alternatif untuk SQL BULK INSERT

  3. Bagaimana cara mendeklarasikan array di dalam Prosedur Tersimpan MS SQL Server?

  4. Gunakan PARSENAME() untuk Mengembalikan Bagian dari Nama Objek di SQL Server

  5. Cara Menghasilkan Data Uji di SQL Server