Keluar dari kueri dalam pernyataan kasus?

8

Saya mencoba menyiapkan kueri, sehingga akan membandingkan dua tanggal dari dua tabel yang berbeda, dan jika keduanya sama, maka kueri keluar. Jika tidak sama, maka kueri akan melanjutkan dan memasukkan beberapa hal. Saya tidak tahu bagaimana cara mendapatkannya untuk melakukan apa yang saya inginkan.

SELECT TOP(1) @dateA=a.someDate
FROM a
ORDER BY DESC;
SELECT TOP(1) @dateB=b.someDate
FROM b
ORDER BY DESC;

CASE WHEN @dateA=@dateB THEN raiseerror('dates equal',20,-1) with log;

Insert statements;

Bantuan apa pun akan sangat dihargai.

thejoker34
sumber
Beberapa varian SQL lainnya memiliki ekspresi dan pernyataan bernama CASE- SQL Server hanya memiliki CASEekspresi.
RDFozz
3
Apakah Anda benar - benar ingin meningkatkan kesalahan? Atau itu hanya upaya untuk keluar?
Kevin

Jawaban:

16

CASE adalah ekspresi (bukan pernyataan) dan tidak dapat digunakan untuk kontrol aliran seperti itu - untuk tidak memanggil perintah, tidak mengembalikan lebih dari satu kolom / nilai, tidak dapat digunakan sebagai perintah sendiri.

Menurut saya, Anda bisa menggunakan IFuntuk meningkatkan kesalahan ketika tanggal sama, jika tidak, jalankan sisipan.

IF @dateA = @dateB 
BEGIN
  raiseerror('dates equal',20,-1) with log;
END
ELSE -- maybe you don't need a batch-aborting, logging error level
BEGIN
  INSERT ...
END

Anda juga bisa melakukannya dengan cara lain. Jalankan sisipan hanya jika tanggal tidak sama , jika tidak, galat:

IF @dateA <> @dateB
BEGIN
  INSERT ...
END
ELSE
BEGIN
  raiserror ...
END

Jika Anda berpikir untuk menggunakan kesalahan hanya untuk tujuan keluar dari menjalankan sisipan, maka Anda hanya dapat menghapus segala sesuatu dari ELSEbawah, karena satu-satunya cara menyisipkan akan berjalan adalah ketika @dateAdan @dateByang tidak sama :

IF @dateA <> @dateB
BEGIN
  INSERT ...
END

Saya telah mengurangi cara untuk menjadi jago tentang hal-hal seperti baris (vs "catatan"), dan kolom (vs "bidang"), tetapi keseluruhan ekspresi vs pernyataan adalah perbedaan yang sangat penting, untuk alasan inilah. Lihat " Rahasia Kotor Ekspresi KASUS ."

Aaron Bertrand
sumber
Sebagian besar jawaban yang bagus, kecuali satu nitpick .. Menggunakan operator '<>' tidak cocok dengan nilai NULL. Jika salah satu dari nilai tanggal Anda adalah NULL, operator 'tidak sama' akan mengembalikan hasil yang tidak terduga. Coba ini "KASUS PILIH KETIKA (1 <> NULL) KEMUDIAN '! =' LAIN '==' AKHIR"
user5151179
1
@ user5151179 Saya cukup yakin Aaron tahu bedanya. Periksa juga bahwa OP dalam pertanyaan mengatakan apa yang ingin dia lakukan ketika kedua tanggal tersebut sama dan bagaimana ketika keduanya tidak sama. Dia sama sekali tidak menyebutkan apa yang ingin mereka lakukan ketika salah satu atau keduanya NULL. Itu masih pengamatan yang baik bahwa dua versi yang disediakan Harun akan melakukan hal-hal yang berbeda dalam kasus itu.
ypercubeᵀᴹ
6

Gunakan IFbukanCASE

 IF @dateA=@dateB 
    raiseerror('dates equal',20,-1) with log;
 ELSE
    BEGIN
        Insert statements;
    END

Ini tentu saja mengasumsikan bahwa Anda sebenarnya ingin meningkatkan kesalahan. Pilihan lainnya adalah:

 IF @dateA<>@dateB 
    BEGIN
        Insert statements;
    END

Sekarang, perhatikan BEGINdan END. Itu akan menjadi penting. yang IFpernyataan (dan ELSE) hanya mempengaruhi perintah tepat di bawah ini. Jika Anda membutuhkan lebih dari satu perintah, Anda perlu BEGIN dan END .

Kenneth Fisher
sumber
2

Jawaban lain menunjukkan bahwa KASUS adalah ekspresi , bukan pernyataan, dan dengan demikian tidak dapat dengan sendirinya mencakup pernyataan (seperti RAISEERRORatau yang lainnya). Jika kondisinya tidak banyak - terutama ketika itu hanya satu syarat, - pernyataan IF adalah pilihan yang sempurna untuk apa yang Anda coba lakukan, seperti juga telah disebutkan.

Namun demikian, tergantung pada skenario Anda, ekspresi CASE masih dapat digunakan, hanya saja tidak persis seperti yang Anda tunjukkan. Secara khusus, jika ada banyak kondisi yang harus diperiksa di mana kecocokan harus menghasilkan serangkaian tindakan yang sama (misalnya menaikkan pengecualian dan mengakhiri skrip), Anda bisa menggunakan ekspresi KASUS dalam pernyataan penugasan yang menyimpan hasil KASUS, kemudian ikuti dengan JIKA memeriksa hasil yang disimpan dan melakukan tindakan yang diperlukan jika perlu, seperti ini:

DECLARE @ErrorMessage varchar(1000);

SET @ErrorMessage =
  CASE WHEN @dateA = @dateB THEN
    'Dates equal'
  CASE WHEN ... /* some other condition */ THEN
    'Some other message'
  .
  .
  .
  ELSE
    ''  -- no message if nothing is wrong;
        -- you can also omit the ELSE branch entirely,
        -- which means the same as ELSE NULL
  END
;

IF @ErrorMessage <> ''
BEGIN
  RAISERROR (@ErrorMessage, 20, -1) WITH LOG;
END;

... /* continue the script */

Dalam hal ini tindakan yang diperlukan adalah meningkatkan pengecualian, tetapi pesan yang dikembalikan dengan pengecualian harus bergantung pada kondisi apa yang diperiksa terlebih dahulu. Pernyataan penugasan menggunakan ekspresi KASUS untuk memilih pesan mana yang akan disimpan dalam @ErrorMessagevariabel.

Anda juga dapat melihat bahwa kesalahan hanya dinaikkan secara bersyarat - hanya jika variabel tersebut benar-benar berisi pesan untuk ditampilkan. Jika nilainya string kosong atau nol, skrip akan terus berlanjut tanpa gangguan.

Andriy M
sumber
0

Apakah Anda memerlukan variabel?

declare @D1 table (dt date);
declare @D2 table (dt date);
insert into @D1 values ('2000-01-01'), ('2000-02-01');
insert into @D2 values ('2000-01-01'), ('2000-02-01');
if (select max(dt) from @D1) = (select max(dt) from @D2)
begin 
   select 'match'
end
else 
begin 
   select 'no match'
end
paparazzo
sumber