Mereka sebenarnya setara, tetapi mereka adalah tipe independen, dan bukan sinonim secara teknis , seperti ROWVERSION
dan TIMESTAMP
- meskipun mereka mungkin telah disebut sebagai sinonim dalam dokumentasi pada satu waktu . Itu adalah arti sinonim yang sedikit berbeda (misalnya mereka tidak dapat dibedakan kecuali dalam nama, tidak satu alias alias untuk yang lain). Ironis kan?
Apa yang saya tafsirkan dari kata-kata dalam MSDN sebenarnya:
Jenis-jenis ini identik, mereka hanya memiliki nama yang berbeda.
Selain type_id
nilainya, semuanya di sini identik:
SELECT * FROM sys.types WHERE name IN (N'numeric', N'decimal');
Saya sama sekali tidak memiliki pengetahuan tentang perbedaan perilaku antara keduanya, dan kembali ke SQL Server 6.5, selalu memperlakukan mereka sebagai 100% dipertukarkan.
untuk DECIMAL (18,2) dan NUMERIC (18,2)? Menugaskan satu ke yang lain secara teknis merupakan "konversi"?
Hanya jika Anda melakukannya secara eksplisit. Anda dapat membuktikan ini dengan mudah dengan membuat tabel dan kemudian memeriksa rencana kueri untuk kueri yang melakukan eksplisit atau - Anda mungkin mengharapkan - konversi tersirat. Ini tabel sederhana:
CREATE TABLE [dbo].[NumDec]
(
[num] [numeric](18, 0) NULL,
[dec] [decimal](18, 0) NULL
);
Sekarang jalankan pertanyaan ini dan tangkap rencana:
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
Seperti yang ditunjukkan dalam SQL Sentry Plan Explorer *, paket tersebut tidak terlalu menarik:
Tetapi tab Ekspresi yakin adalah:
Seperti yang saya komentari di atas, kami memiliki konversi eksplisit tempat kami memintanya, tetapi tidak ada konversi eksplisit di mana kami mungkin mengharapkannya. Tampaknya pengoptimal memperlakukan mereka juga dapat dipertukarkan.
Silakan dan coba tes ini juga (data dan indeks).
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]);
Sekarang jalankan query ini:
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;
Plan tidak memiliki konversi (sebenarnya tab Ekspresi kosong):
Bahkan ini tidak mengarah pada konversi yang tidak terduga. Tentu saja Anda melihatnya di RHS dalam predikat, tetapi dalam kasus apa pun konversi tidak boleh terjadi terhadap data kolom untuk memfasilitasi pencarian (apalagi memaksa pemindaian).
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);
Secara pribadi, saya lebih suka menggunakan istilah ini DECIMAL
hanya karena jauh lebih akurat dan deskriptif. BIT
juga "numerik".
* Disclaimer: I work for SQL Sentry.