NUMERICとDECIMALに違いはありますか?


47

SQL ServerのNUMERICとDECIMALのデータ型は同じように機能することを知っています。それらを作成するための構文は同じで、格納できる値の範囲は同じです。

ただし、MSDNのドキュメントでは、この2つの関係を次のように説明しています。

numericは機能的には10進数と同等です。

通常、「機能的に同等」という修飾子を見ると、2つのことはまったく同じではなく、外部から区別できない 2つの異なるタイプであることを意味します。

この意味は本当ですか?NUMERICとDECIMALには、たまたま外部の観測者と同じ動作をする違いがありますか?または、それらは実際に同等ですか、たとえば、NUMERICはDECIMALの従来の同義語ですか?


1
SQL Server 以外のサポートに違いがあるかもしれません。たとえば、SSISのこの奇妙な違いに気付いたばかりです。
アーロンバートランド

回答:


56

彼らは実際には同等ですが、彼らは独立したタイプ、およびでない技術的に同義語などROWVERSIONTIMESTAMPけれども- 彼らは一度にドキュメントの同義語と呼ばれている可能性があり。これは同義語のわずかに異なる意味です(たとえば、名前以外は区別できません。一方が他方のエイリアスではありません)。皮肉ですよね?

MSDNの文言から私が解釈するのは、実際には次のとおりです。

これらのタイプは同一であり、名前が異なるだけです。

以外のtype_id値は、ここですべてが同じです。

SELECT * FROM sys.types WHERE name IN (N'numeric', N'decimal');

この2つの動作の違いについてはまったく知りません。SQLServer 6.5に戻ると、常に100%交換可能として扱ってきました。

DECIMAL(18,2)およびNUMERIC(18,2)の場合?一方を他方に割り当てることは、技術的には「変換」ですか?

明示的に行う場合のみ。これを簡単に証明するには、テーブルを作成してから、明示的または-予想される-暗黙的な変換を実行するクエリのクエリプランを調べます。簡単な表を次に示します。

CREATE TABLE [dbo].[NumDec]
(
    [num] [numeric](18, 0) NULL,
    [dec] [decimal](18, 0) NULL
);

次に、これらのクエリを実行し、計画をキャプチャします。

DECLARE @num NUMERIC(18,0);
DECLARE @dec DECIMAL(18,0);

SELECT 
  CONVERT(DECIMAL(18,0), [num]), -- conversion
  CONVERT(NUMERIC(18,0), [dec])  -- conversion
FROM dbo.NumDec
UNION ALL SELECT [num],[dec] 
  FROM dbo.NumDec WHERE [num] = @dec  -- no conversion
UNION ALL SELECT [num],[dec] 
  FROM dbo.NumDec WHERE [dec] = @num; -- no conversion

SQL Sentry Plan Explorer *に示されているように、計画はあまり面白くありません。

ここに画像の説明を入力してください

ただし、[式]タブは次のとおりです。

ここに画像の説明を入力してください

上でコメントしたように、私たちはそれらを要求した明示的な変換はありますが、期待していたかもしれない明示的な変換はありません。オプティマイザーはそれらを交換可能として扱っているようです。

先に進んで、このテストも試してください(データとインデックス)。

CREATE TABLE [dbo].[NumDec2]
(
    [num] [numeric](18, 2) NULL,
    [dec] [decimal](18, 2) NULL
);

INSERT dbo.NumDec2([num],[dec])
SELECT [object_id] + 0.12, [object_id] + 0.12
  FROM sys.all_columns;

CREATE INDEX [ix_num] ON dbo.NumDec2([num]);
CREATE INDEX [ix_dec] ON dbo.NumDec2([dec]);

次のクエリを実行します。

DECLARE @num NUMERIC(18,2) = -1291334356.88,
        @dec NUMERIC(18,2) = -1291334356.88;

SELECT [dec] FROM dbo.NumDec2 WHERE [dec] = @num
UNION ALL
SELECT [num] FROM dbo.NumDec2 WHERE [num] = @dec;

プランには変換がありません(実際には[式]タブは空です):

ここに画像の説明を入力してください

これらであっても、予期しない変換は発生しません。もちろん、述語でRHSに表示されますが、シークを容易にするために列データに対して変換を行う必要はありませんでした(スキャンの強制力ははるかに小さくなります)。

SELECT [dec] FROM dbo.NumDec2 WHERE [dec] = CONVERT(DECIMAL(18,2), @num)
UNION ALL
SELECT [dec] FROM dbo.NumDec2 WHERE [dec] = CONVERT(DECIMAL(18,2), @dec)
UNION ALL
SELECT [num] FROM dbo.NumDec2 WHERE [num] = CONVERT(NUMERIC(18,2), @num)
UNION ALL
SELECT [num] FROM dbo.NumDec2 WHERE [num] = CONVERT(NUMERIC(18,2), @dec)
UNION ALL
SELECT [num] FROM dbo.NumDec2 WHERE [num] = CONVERT(DECIMAL(18,2), @num)
UNION ALL
SELECT [num] FROM dbo.NumDec2 WHERE [num] = CONVERT(DECIMAL(18,2), @dec)
UNION ALL
SELECT [dec] FROM dbo.NumDec2 WHERE [dec] = CONVERT(NUMERIC(18,2), @num)
UNION ALL
SELECT [dec] FROM dbo.NumDec2 WHERE [dec] = CONVERT(NUMERIC(18,2), @dec);

個人的には、この用語はDECIMALはるかに正確で記述的であるという理由で使用することを好みます。BITも「数値」です。

* Disclaimer: I work for SQL Sentry.

SQLは、たとえばDECIMAL(18,2)とDECIMAL(18,0)を「異なるタイプ」として扱うことを知っています。これはDECIMAL(18,2)とNUMERIC(18,2)でも同じことを意味しますか?一方を他方に割り当てることは、技術的には「変換」ですか?
KutuluMike 14

@MichaelEdenfield新しい質問に対する回答を更新しました。
アーロンバートランド

1
私はこれが古い答えであることを知っていますが、数値と小数が同義語であると考えるとSQL Serverでエラーが発生するケースを見つけました他の誰かがそれから利益を得る可能性がある場合に備えて、ここにコメントを残すべきだと考えました。
ゾハルPeled

@AaronBertrand役に立つので、あなたの答えに投票しました。どちらのタイプも同じように見えますが、その場合、なぜ異なる名前が付けられているのですか?歴史的な理由はありますか?
イヴァンジーニョ

@Ivanzinhoあなたの質問が修辞的であるかどうかはわかりません、たくさんの理論があります(このページとあなたがリンクした答えの両方)、しかしあなたが決定的な答えを望むなら、あなたはおそらく運が悪いでしょう。最初にSQL Serverで両方のタイプを実装した元のエンジニアを追跡し、その実装とその時点での標準の解釈の両方のメモリに依存する必要があります。
アーロンバートランド

15

ただし、実際には同じです(SQL 2003標準から)。

21)数値は、で指定された小数精度とスケールで、正確な数値データ・タイプを指定 precisionし、scale

22)DECIMALは、で指定された10進スケールscaleと、指定されたの値以上の 実装定義の 10進精度で、データ型の正確な数値を指定しますprecision


5
基本的な質問(そして答えはノーだと思います)、SQL ServerはNUMERICとは異なるDECIMALの精度を実装しましたか。標準が実行できると言うことは、実際に実行されたものよりもはるかに重要ではありません。
アーロンバートランド

5
ありがとう。これは、名前が異なるが動作が同じである2つのタイプが存在する理由についての追加の質問に対する優れた回答です。
ゲイブ14
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.