Saya ingin memasukkan data ke tabel saya, tetapi hanya memasukkan data yang belum ada di database saya.
Ini kode saya:
ALTER PROCEDURE [dbo].[EmailsRecebidosInsert]
(@_DE nvarchar(50),
@_ASSUNTO nvarchar(50),
@_DATA nvarchar(30) )
AS
BEGIN
INSERT INTO EmailsRecebidos (De, Assunto, Data)
VALUES (@_DE, @_ASSUNTO, @_DATA)
WHERE NOT EXISTS ( SELECT * FROM EmailsRecebidos
WHERE De = @_DE
AND Assunto = @_ASSUNTO
AND Data = @_DATA);
END
Dan kesalahannya adalah:
Msg 156, Level 15, Status 1, Prosedur EmailsRecebidosInsert, Baris 11
Sintaksis salah di dekat kata kunci 'WHERE'.
sql
sql-server
sql-server-2008
stored-procedures
Francisco Carvalho
sumber
sumber
insert
pernyataan selalu merupakan satu transaksi. Ini bukan seolah-olah SQL Server mengevaluasi subquery pertama dan kemudian di beberapa titik kemudian, dan tanpa memegang kunci, melanjutkan untuk melakukan penyisipan.Jawaban:
bukannya Kode di bawah ini
ubah dengan
Diperbarui: (terima kasih kepada @Marc Durdin karena menunjuk)
Perhatikan bahwa di bawah beban tinggi, ini kadang-kadang masih gagal, karena koneksi kedua dapat lulus tes JIKA TIDAK ADA sebelum koneksi pertama mengeksekusi INSERT, yaitu kondisi balapan. Lihat stackoverflow.com/a/3791506/1836776 untuk jawaban yang bagus tentang mengapa bahkan membungkus transaksi tidak menyelesaikan masalah ini.
sumber
select *
dalam kasus ini tidak ada bedanya karena digunakan dalamEXISTS
klausa. SQL Server akan selalu mengoptimalkannya dan telah melakukannya sejak lama. Karena saya sudah sangat tua, saya biasanya menulis pertanyaan iniEXISTS (SELECT 1 FROM...)
tetapi tidak diperlukan lagi.Bagi mereka yang mencari cara tercepat , saya baru - baru ini menemukan tolok ukur ini di mana tampaknya menggunakan "INSERT SELECT ... EXCEPT SELECT ..." ternyata menjadi yang tercepat untuk 50 juta rekaman atau lebih.
Berikut beberapa contoh kode dari artikel (blok kode ke-3 adalah yang tercepat):
sumber
Saya akan menggunakan gabungan:
sumber
Coba kode di bawah ini
sumber
The
INSERT
perintah tidak memilikiWHERE
klausul - Anda harus menulis seperti ini:sumber
Saya melakukan hal yang sama dengan SQL Server 2012 dan berhasil
sumber
Bergantung pada versi Anda (2012?) Dari SQL Server selain dari JIKA ADA Anda juga dapat menggunakan MERGE seperti:
sumber
SQL berbeda, prinsip yang sama. Hanya masukkan jika klausa di mana tidak ada gagal
sumber
Seperti dijelaskan dalam kode di bawah ini: Jalankan pertanyaan di bawah ini dan verifikasi diri Anda.
Sisipkan catatan:
Sekarang, coba masukkan catatan yang sama lagi:
Masukkan catatan yang berbeda:
sumber
Anda bisa menggunakan
GO
perintah. Itu akan memulai kembali pelaksanaan pernyataan SQL setelah kesalahan. Dalam kasus saya, saya memiliki beberapa pernyataan INSERT 1000, di mana beberapa catatan itu sudah ada dalam database, saya hanya tidak tahu yang mana. Saya menemukan bahwa setelah memproses beberapa 100, eksekusi hanya berhenti dengan pesan kesalahan yang tidak bisaINSERT
karena catatan sudah ada. Cukup menjengkelkan, tetapi menempatkanGO
ini diselesaikan. Ini mungkin bukan solusi tercepat, tetapi kecepatan bukanlah masalah saya.sumber
GO
Apakah pemisah batch? Itu tidak membantu mencegah catatan duplikat.