エラーメッセージの「SET」の意味「NULL値は集計またはその他のSET操作によって削除されます」


18

今日、同僚のスクリプトを実行しているときに、上記の「ANSI警告」メッセージが表示されました(そして、多くのステートメントのどれが警告を表示したのかわかりません)。

過去に私はそれを無視していました。私はヌルを自分で避けているので、それらを排除するものは私の本では良いことです!しかし、今日、「SET」という言葉が文字通り私に叫び、私はこの文脈でその言葉の意味が何を意味するのかわからないことに気付きました。

私が最初に考えたのは、大文字であるという事実に基づいて、SETキーワードを参照しており、「割り当て」を意味しているということです。

UPDATE <table> SET ...

...ON DELETE SET NULL...

SET IDENTITY_INSERT <table> ON

SQL Serverヘルプによると、「ANSI警告」機能はISO / ANSI SQL-92に基づいています。この仕様では、サブセクションのタイトル、つまりタイトルの場合、データ割り当てセクション。ただし、エラーメッセージをすばやくグーグルで調べた後、SELECT割り当てが関係していないように見えるクエリの例を見ることができます。

SQL Serverの警告の文言に基づいた私の2番目の考えは、集合の数学的意味が暗示されているということでした。ただし、SQLの集約が厳密に言うと集合演算であるとは思いません。SQL Serverチームがそれを集合演算であると見なしている場合でも、「集合」という単語を大文字にする目的は何ですか?

グーグル検索中に、SQL Serverのエラーメッセージに気付きました。

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

ここでの同じケースでの「SET操作」という同じ言葉は、IDENTITY_INSERTプロパティの割り当てを指しているだけで、最初の考えに戻ります。

誰かが問題に光を当てることはできますか?


私は常に、それが行のセットに対する操作を意味すると想定していました。
マーティンスミス

以来、私はそうは思いません@MartinSmith SETキーワードのような完全な大文字で常にある
JNK

@JNK-それについて考えると、私はその警告を発生させる他の非集約操作があるはずだと思うので、それが何であるかを見つければそれを説明するかもしれません!
マーティンスミス

SELECT * FROM sys.messages WHERE text LIKE '%SET operation%'SETキーワードを示すと思われる他の3つの結果が得られます。
マーティンスミス

さらに検索を行いましたが、実際には数学セットのように集合演算を参照している可能性があります。SS 2kのドキュメントにset operationsUNIONINTERSECTおよびを参照する多くの参照が見つかりましたが、これらの状況でEXCEPTはエラーを思い付くことができませんNULL。レガシーエラーメッセージかもしれません。
JNK

回答:


13

私はSQL-92仕様に目を通すだけで、この質問を思い出させる一節を見ました。

以下に示すように、実際にはこの状況に対して規定された警告があります

b)それ以外の場合、TX <value expression>をTの各行に適用し、ヌル値を削除した結果である単一列のテーブルとします。1つ以上のヌル値が除去されると、完了条件が発生します。警告-ヌル値がset functionで除去されます

SETSQL Serverエラーメッセージのは、そのエラーメッセージの集合関数への参照であると想定していますが、同義語であることがわかる限り、集計と他の集合関数を区別する理由はわかりません。文法の関連ビットは以下のとおりです。

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

素早い回答

「その他のSET *は、おそらく古いSQL Serverバージョンに関連しています。

SQL Server 6.5および7で作業したとき、私はそれをより昔に見たことがありますが、それはしばらく経っています。多くの癖が解決されました+ SQL Serverはより標準に準拠しています

より長いです:

現在、メッセージはSET ANSI_WARNINGSデフォルトでに制御されていONます。
これは純粋に

  • 警告は、集計内のNULL値によって生成されます。
  • varchar型フィールドの挿入/更新でサイレント切り捨てが発生します

一例:

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;

与える

(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)

もう一つの例:

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

個人的には、この警告を無視し、SET ANSI_WARNINGSをONのままにします。これは、計算列とそれをOFFに設定したインデックス付きビューに対する他の結果のためです。

最後に、この警告を生成するトリガーまたは計算列またはインデックス付きビューがある可能性があります


エラーメッセージの言い回しは、明らかに、私にとってもNULLを排除できる非集約操作がある(またはあった)ことを暗示しています。
マーティンスミス

@マーティンスミス:同意する。私の(新しい)最後の声明によると、それは間接的かもしれません。または、計画に見られる最適化戦略
gbn

SQL Server 7.0よりも古いドキュメントは、どこからでもオンラインになっていないようです。
マーティンスミス

1
例(この古いものを見つけるのは難しい):kbalertz.com/Feedback.aspx?kbNumber
149921

1
実際には、メッセージのSQL Server 7.0バージョンは単なる警告であるように見えますが、集計からNull値が削除されました。SET operationビットは2000年までは添加しなかった
マーティン・スミス

2

警告の反対側は、「SET」操作ではなく「set」操作を指します-これはメッセージのバグのように見えます-たとえば、ウィンドウ関数でも生成されます:

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
それはまだ集約一部かかわらを参照だように思えるMAX()
JNK

それは「集約部分」と呼ばれますか?私はあなたが、もちろん何を意味するか知っているが、それらは異なる操作である-例えば、比較select max(foo) from (values (1), (2), (null)) as t(foo) where 1=2;select max(foo) over() from (values (1), (2), (null)) as t(foo) where 1=2;
ジャック・ダグラス

2
それは集約関数です:)エラーはを指していると思いますMAX()。2番目の例では、ウィンドウ関数を使用した操作の順序をさらに行う必要があると思います。
-JNK

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.