Arti 'SET' dalam pesan kesalahan 'Nilai kosong dihapus oleh operasi agregat atau SET lainnya'


18

Saya melihat pesan 'peringatan ANSI' di atas hari ini ketika menjalankan skrip kolega (dan saya tidak tahu yang mana dari banyak pernyataan yang menyebabkan peringatan ditampilkan).

Di masa lalu saya telah mengabaikannya: Saya menghindari nol dan jadi apa pun yang akan menghilangkannya adalah hal yang baik dalam buku saya! Namun, hari ini kata 'SET' secara harfiah meneriaki saya dan saya menyadari saya tidak tahu apa arti kata itu dalam konteks ini.

Pikiran pertama saya, berdasarkan fakta ini adalah huruf besar, adalah merujuk pada SETkata kunci dan berarti 'penugasan', seperti dalam

UPDATE <table> SET ...

...ON DELETE SET NULL...

SET IDENTITY_INSERT <table> ON

Menurut Bantuan SQL Server, fitur 'peringatan ANSI' didasarkan pada ISO / ANSI SQL-92, spesifikasi yang hanya menggunakan satu kali penggunaan istilah 'Atur operasi' dalam judul subbagian, maka dalam kasus judul, dalam bagian penugasan data. Namun, setelah Googling cepat dari pesan kesalahan saya melihat contoh yang SELECTkueri dengan tampaknya tidak ada tugas yang terlibat.

Pikiran kedua saya, berdasarkan kata-kata peringatan SQL Server, adalah bahwa makna matematika dari himpunan tersirat. Namun, saya tidak berpikir bahwa agregasi dalam SQL benar-benar berbicara tentang operasi yang ditetapkan. Bahkan jika tim SQL Server menganggapnya sebagai operasi himpunan, apa tujuan dari menempatkan kata 'himpunan' di ibukota?

Sementara Googling saya melihat pesan kesalahan SQL Server:

Table 'T' does not have the identity property. Cannot perform SET operation.

Kata-kata yang sama 'SET operasi' dalam kasus yang sama di sini hanya dapat merujuk pada penugasan IDENTITY_INSERTproperti, yang membawa saya kembali ke pikiran pertama saya.

Adakah yang bisa menjelaskan masalah ini?


Saya selalu menganggap itu berarti operasi pada set baris.
Martin Smith

@ MartinSmith Saya tidak berpikir demikian karena SETselalu dalam topi penuh seperti kata kunci
JNK

@JNK - Ya saat memikirkannya saya berasumsi pasti ada beberapa operasi non-agregat lainnya yang menimbulkan peringatan itu jadi saya kira jika kita mencari tahu apa yang mungkin menjelaskannya!
Martin Smith

SELECT * FROM sys.messages WHERE text LIKE '%SET operation%'memberikan 3 hasil lain yang semuanya sepertinya mengindikasikan SETkata kunci juga.
Martin Smith

Saya melakukan beberapa pencarian lagi dan mungkin sebenarnya merujuk ke operasi set seperti pada set matematika. Saya menemukan banyak referensi dalam SS 2k docs untuk set operationsmerujuk ke UNIONdan INTERSECTdan EXCEPT, tetapi saya tidak bisa mendapatkan kesalahan untuk muncul NULLdalam situasi seperti itu. Saya pikir ini mungkin pesan kesalahan lama.
JNK

Jawaban:


13

Saya hanya melihat melalui Spesifikasi SQL-92 dan melihat bagian yang mengingatkan saya pada pertanyaan ini.

Sebenarnya ada peringatan yang ditentukan untuk situasi ini seperti yang ditunjukkan di bawah ini

b) Kalau tidak, biarkan TX menjadi tabel satu kolom yang merupakan hasil dari penerapan <value expression>ke setiap baris T dan menghilangkan nilai nol. Jika satu atau lebih nilai nol dihilangkan, maka kondisi penyelesaian dinaikkan: peringatan - nilai nol dihilangkan dalam fungsi yang ditetapkan .

Saya berasumsi bahwa SETdalam Pesan Kesalahan SQL Server adalah referensi ke fungsi set pesan kesalahan itu meskipun saya tidak yakin mengapa itu akan membuat perbedaan antara agregat dan fungsi-fungsi himpunan lainnya, sejauh yang saya bisa lihat mereka identik. Bit tata bahasa yang relevan ada di bawah.

6.5  <set function specification>

         Function

         Specify a value derived by the application of a function to an
         argument.

         Format

         <set function specification> ::=
                COUNT <left paren> <asterisk> <right paren>
              | <general set function>

         <general set function> ::=
                <set function type>
                    <left paren> [ <set quantifier> ] <value expression> <right paren>


         <set function type> ::=
              AVG | MAX | MIN | SUM | COUNT

         <set quantifier> ::= DISTINCT | ALL

9

Jawaban cepat

"SET lain * mungkin terkait dengan versi SQL Server yang lebih lama.

Saya biasa melihatnya lebih kembali ketika saya bekerja dengan SQL Server 6.5 dan 7 saya yakin, tapi sudah lama. Banyak quirks telah diatasi + SQL Server mengikuti standar lebih banyak

Lebih lama:

Saat ini, pesan dikendalikan oleh SET ANSI_WARNINGSdefaultnya ON.
Ini berhubungan murni dengan apakah

  • peringatan dihasilkan oleh nilai NULL dalam agregat.
  • pemotongan diam terjadi pada saat menyisipkan / memperbarui bidang tipe varchar

Satu contoh:

DECLARE @foo TABLE (bar int NULL);
INSERT @foo VALUES (1), (2), (NULL);

SET ANSI_WARNINGS ON;
SELECT SUM(bar) FROM @foo;
SET ANSI_WARNINGS OFF;

SELECT SUM(bar) FROM @foo;

memberi

(3 row(s) affected)
---- -----------
ON   3
Warning: Null value is eliminated by an aggregate or other SET operation.
(1 row(s) affected)
---- -----------
OFF  3
(1 row(s) affected)

Contoh lain:

DECLARE @foo TABLE (bar varchar(5) NULL);
SET ANSI_WARNINGS ON;
INSERT @foo VALUES ('123456'); -- error
GO
DECLARE @foo TABLE (bar varchar(5) NULL);
SET ANSI_WARNINGS OFF;
INSERT @foo VALUES ('123456'); -- OK
GO

Secara pribadi, saya mengabaikan peringatan itu dan membiarkan SET ANSI_WARNINGS ON karena konsekuensi lain untuk kolom yang dihitung dan tampilan indeks pengaturannya OFF.

Akhirnya, mungkin ada pemicu atau kolom yang dihitung atau tampilan yang diindeks menghasilkan peringatan ini di suatu tempat


Ungkapan pesan kesalahan pasti menyiratkan bahwa ada (atau) beberapa operasi non-agregat yang juga bisa menghilangkan NULL kepada saya.
Martin Smith

@ Martin Smith: setuju. Itu bisa saja tidak langsung sesuai dengan pernyataan terakhir saya (baru). Atau beberapa strategi pengoptimal yang akan terlihat dalam rencana
gbn

Malu bahwa dokumen untuk apa pun yang lebih lama dari SQL Server 7.0 tampaknya tidak online di mana saja.
Martin Smith

1
contoh (sulit untuk menemukan barang lama ini): kbalertz.com/Feedback.aspx?kbNumber=149921/EN-US
gbn

1
Meskipun sebenarnya tampak seolah-olah versi SQL Server 7.0 dari pesan itu hanya Peringatan: Nilai kosong dihapus dari agregat. . The SET operationbit tidak ditambahkan sampai tahun 2000.
Martin Smith

2

Sisi lain dari peringatan mengacu pada operasi 'set' bukan operasi 'SET' - yang terlihat seperti bug pesan bagi saya - misalnya, ia juga diproduksi dengan fungsi windowing:

select max(foo) over() as max_foo from (values (1), (2), (null)) as t(foo);
/*
max_foo
-------
2
2
2

Warning: Null value is eliminated by an aggregate or other SET operation.
*/

1
Sepertinya itu masih mengacu pada bagian agregasiMAX()
JNK

Apakah itu disebut 'bagian agregasi'? Saya tahu apa yang Anda maksud tentu saja, tetapi mereka adalah operasi yang berbeda - misalnya membandingkan select max(foo) from (values (1), (2), (null)) as t(foo) where 1=2;versusselect max(foo) over() from (values (1), (2), (null)) as t(foo) where 1=2;
Jack Douglas

2
Ini fungsi agregat :) Saya percaya kesalahan ini merujuk MAX(). Saya pikir Anda contoh kedua harus berbuat lebih banyak dengan urutan operasi menggunakan fungsi jendela.
JNK

ok - lihat apa yang Anda maksud dari dokumen SS
Jack Douglas
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.