Aslında eşdeğerdirler, ancak bağımsız türlerdir ve teknik olarak eşanlamlılar değildirler , ROWVERSION
ve TIMESTAMP
- ve bir kerede belgelerde eşanlamlılar olarak adlandırılmış olsalar bile . Bu, eş anlamlılığın biraz farklı bir anlamıdır (örneğin, isim dışında ayırt edilemez, biri diğeri için bir takma ad değildir). İronik değil mi?
MSDN'deki ifadelerden yorumladığım şey aslında:
Bu türler aynı, sadece farklı isimler var.
type_id
Değerler dışında, buradaki her şey aynı:
SELECT * FROM sys.types WHERE name IN (N'numeric', N'decimal');
İkisi arasındaki davranış farklılıkları hakkında hiçbir bilgim yok ve SQL Server 6.5'e geri dönüyoruz, onlara her zaman% 100 değiştirilebilir olarak davrandılar.
DECIMAL (18,2) ve NUMERIC (18,2) için mi? Birini diğerine atamak teknik olarak bir "dönüşüm" mü?
Sadece açıkça yaparsan. Bunu bir tablo oluşturarak ve ardından açık veya doğrudan bir sorgulama yapan sorgular için sorgu planını inceleyerek kolayca kanıtlayabilirsiniz. İşte basit bir tablo:
CREATE TABLE [dbo].[NumDec]
(
[num] [numeric](18, 0) NULL,
[dec] [decimal](18, 0) NULL
);
Şimdi bu sorguları çalıştırın ve planı yakalayın:
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'da * gösterildiği gibi , plan gerçekten ilginç değil:
Ancak İfadeler sekmesi kesinlikle:
Yukarıda yorum yaptığım gibi, istediğimiz yerde açıkça dönüşümler yaptık, ancak beklentilerimizi beklediğimiz açıkça bir dönüşüm yok. Optimizer de onlara değişebilir gibi görünüyor.
Devam edin ve bu testi de deneyin (veriler ve dizinler).
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]);
Şimdi bu sorguyu çalıştırın:
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;
Planda dönüşüm yok (aslında İfadeler sekmesi boş):
Bunlar bile beklenmedik dönüşümlere yol açmaz. Tabii ki, bunu RHS'de belirttiğinizde görüyorsunuz, ancak hiçbir durumda arama işlemini kolaylaştırmak için sütun verisine karşı herhangi bir dönüşüm gerçekleşmedi (taramayı çok daha az zorla).
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);
Şahsen ben DECIMAL
sadece daha doğru ve açıklayıcı bir terim olduğu için terimi kullanmayı tercih ediyorum . BIT
"sayısal" da.
* Disclaimer: I work for SQL Sentry.