Chúng thực sự tương đương, nhưng chúng là các loại độc lập, và không phải là từ đồng nghĩa về mặt kỹ thuật , như ROWVERSION
và TIMESTAMP
- mặc dù chúng có thể được gọi là từ đồng nghĩa trong tài liệu cùng một lúc . Đó là một ý nghĩa hơi khác của từ đồng nghĩa (ví dụ: chúng không thể phân biệt được ngoại trừ trong tên, không phải là một bí danh cho người khác). Mỉa mai phải không?
Những gì tôi diễn giải từ các từ trong MSDN thực sự là:
Những loại này giống hệt nhau, chúng chỉ có tên khác nhau.
Khác với các type_id
giá trị, mọi thứ ở đây đều giống hệt nhau:
SELECT * FROM sys.types WHERE name IN (N'numeric', N'decimal');
Tôi hoàn toàn không có kiến thức về bất kỳ sự khác biệt về hành vi nào giữa hai người và quay trở lại SQL Server 6.5, luôn coi họ là 100% có thể hoán đổi cho nhau.
cho DECIMAL (18,2) và NUMERIC (18,2)? Gán cái này cho cái kia về mặt kỹ thuật là "chuyển đổi"?
Chỉ khi bạn làm như vậy rõ ràng. Bạn có thể chứng minh điều này một cách dễ dàng bằng cách tạo một bảng và sau đó kiểm tra kế hoạch truy vấn cho các truy vấn thực hiện rõ ràng hoặc - bạn có thể mong đợi - chuyển đổi ngầm định. Đây là một bảng đơn giản:
CREATE TABLE [dbo].[NumDec]
(
[num] [numeric](18, 0) NULL,
[dec] [decimal](18, 0) NULL
);
Bây giờ hãy chạy các truy vấn này và nắm bắt kế hoạch:
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
Như được hiển thị trong SQL Sentry Plan Explorer *, kế hoạch không thực sự thú vị:
Nhưng tab Biểu thức chắc chắn là:
Như tôi đã nhận xét ở trên, chúng tôi có các chuyển đổi rõ ràng nơi chúng tôi đã yêu cầu chúng, nhưng không có chuyển đổi rõ ràng nơi chúng tôi có thể đã mong đợi chúng. Có vẻ như trình tối ưu hóa cũng coi chúng là có thể hoán đổi cho nhau.
Đi trước và thử kiểm tra này, quá (dữ liệu và chỉ mục).
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]);
Bây giờ hãy chạy truy vấn này:
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;
Gói không có chuyển đổi (trên thực tế, tab Biểu thức trống):
Ngay cả những điều này không dẫn đến bất kỳ chuyển đổi bất ngờ. Tất nhiên bạn thấy nó trên RHS trong vị ngữ, nhưng trong mọi trường hợp, không có bất kỳ chuyển đổi nào phải xảy ra đối với dữ liệu cột để tạo điều kiện cho việc tìm kiếm (ít hơn một lần quét).
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);
Cá nhân, tôi thích sử dụng thuật ngữ này DECIMAL
chỉ vì nó chính xác và mô tả hơn nhiều. BIT
là "số" quá.
* Disclaimer: I work for SQL Sentry.