Dưới đây là danh sách chứa các kiểu dữ liệu SQL Server, theo thứ tự ưu tiên.
- kiểu dữ liệu do người dùng xác định (cao nhất)
-
sql_variant
-
xml
-
datetimeoffset
-
datetime2
-
datetime
-
smalldatetime
-
date
-
time
-
float
-
real
-
decimal
-
money
-
smallmoney
-
bigint
-
int
-
smallint
-
tinyint
-
bit
-
ntext
-
text
-
image
-
timestamp
-
uniqueidentifier
-
nvarchar
(bao gồmnvarchar(max)
) -
nchar
-
varchar
(bao gồmvarchar(max)
) -
char
-
varbinary
(bao gồmvarbinary(max)
) -
binary
(thấp nhất)
Khi bạn sử dụng một toán tử để kết hợp các toán hạng của các kiểu dữ liệu khác nhau, kiểu dữ liệu có mức độ ưu tiên thấp hơn trước tiên sẽ được chuyển đổi thành kiểu dữ liệu có mức độ ưu tiên cao hơn.
Nếu chuyển đổi không phải là chuyển đổi ngầm được hỗ trợ, thì lỗi sẽ được trả về.
Nếu cả hai toán hạng có cùng kiểu thì không có chuyển đổi nào được thực hiện (hoặc cần thiết) và kết quả của phép toán sử dụng kiểu dữ liệu của toán hạng.
Ví dụ
Dưới đây là một ví dụ về chuyển đổi ngầm thành công:
SELECT 1 * 1.00;
Kết quả:
1.00
Ở đây, toán hạng bên trái đã được chuyển đổi thành kiểu dữ liệu của toán hạng bên phải.
Đây là một cách rõ ràng hơn để làm điều đó:
DECLARE
@n1 INT,
@n2 DECIMAL(5, 2);
SET @n1 = 1;
SET @n2 = 1;
SELECT @n1 * @n2;
Kết quả:
1.00
Trong trường hợp này, tôi đã khai báo toán hạng bên trái một cách rõ ràng là INT
và toán hạng bên phải là DECIMAL(5, 2)
.
Chúng tôi có thể kiểm tra thêm kết quả bằng sys.dm_exec_describe_first_result_set
chức năng quản lý động hệ thống.
Hàm này cho phép chúng tôi kiểm tra kiểu dữ liệu của mỗi cột được trả về trong một truy vấn:
SELECT
system_type_name,
max_length,
[precision],
scale
FROM sys.dm_exec_describe_first_result_set(
'DECLARE @n1 INT, @n2 DECIMAL(5, 2);
SET @n1 = 1;
SET @n2 = 1;
SELECT @n1, @n2, @n1 * @n2;',
null,
0);
Kết quả:
+--------------------+--------------+-------------+---------+ | system_type_name | max_length | precision | scale | |--------------------+--------------+-------------+---------| | int | 4 | 10 | 0 | | decimal(5,2) | 5 | 5 | 2 | | decimal(16,2) | 9 | 16 | 2 | +--------------------+--------------+-------------+---------+
Ở đây, chúng ta có thể thấy rằng mỗi hàng đại diện cho mỗi cột được trả về bởi truy vấn. Do đó, cột đầu tiên là INT
, cột thứ hai là DECIMAL(5,2)
và cột thứ ba a DECIMAL(16,2)
.
Vì vậy, SQL Server thực sự trả về một DECIMAL(16,2)
, mặc dù giá trị thập phân ban đầu là DECIMAL(5,2)
.
Ví dụ về Lỗi chuyển đổi
Như đã đề cập, nếu chuyển đổi không phải là chuyển đổi ngầm được hỗ trợ, thì lỗi sẽ được trả về:
SELECT 'Age: ' + 10;
Kết quả:
Msg 245, Level 16, State 1, Line 1 Conversion failed when converting the varchar value 'Age: ' to data type int.
Trong trường hợp này, tôi đang cố gắng nối một chuỗi (VARCHAR
) và một số (INT
). Xem dưới dạng INT
có mức độ ưu tiên cao hơn VARCHAR
, SQL Server đã cố gắng chuyển đổi hoàn toàn chuỗi thành INT
.
Điều này không thành công, bởi vì chuỗi này không thể được chuyển đổi thành một số nguyên.
Để khắc phục điều này, trước tiên chúng ta có thể chuyển đổi INT
thành VARCHAR
:
SELECT 'Age: ' + CAST(10 AS VARCHAR(2));
Kết quả:
Age: 10
Bây giờ cả hai toán hạng đều có cùng kiểu dữ liệu và do đó SQL Server thực hiện hoạt động thành công mà không cần thực hiện bất kỳ chuyển đổi ngầm nào.
Một cách khác để thực hiện thao tác cụ thể này là với CONCAT()
chức năng:
SELECT CONCAT('Age: ', 10);
Kết quả:
Age: 10
CONCAT()
hàm là một hàm chuỗi và do đó hoàn toàn chuyển đổi tất cả các đối số thành các kiểu chuỗi trước khi nối. Do đó, chúng tôi không cần thực hiện chuyển đổi rõ ràng.
Tuy nhiên, nếu toán hạng chuỗi có thể được chuyển đổi hoàn toàn thành một số, thì nó sẽ không gây ra lỗi khi sử dụng +
nhà điều hành:
SELECT '10' + 10;
Kết quả:
20
Nhưng trong trường hợp này, +
toán tử biến thành một toán tử toán học bổ sung, thay vì một toán tử nối chuỗi.