Mã định danh duy nhất có thêm ký tự vẫn khớp


19

Chúng tôi đang sử dụng SQL Server 2012 với một mã định danh duy nhất và chúng tôi nhận thấy rằng khi thực hiện các lựa chọn có thêm các ký tự được thêm vào cuối (không phải là 36 ký tự), nó vẫn trả về kết quả khớp với UUID.

Ví dụ:

select * from some_table where uuid = '7DA26ECB-D599-4469-91D4-F9136EC0B4E8' 

trả về hàng với uuid 7DA26ECB-D599-4469-91D4-F9136EC0B4E8.

Nhưng nếu bạn chạy:

select * from some_table where uuid = '7DA26ECB-D599-4469-91D4-F9136EC0B4E8EXTRACHARS'

nó cũng trả về hàng với uuid 7DA26ECB-D599-4469-91D4-F9136EC0B4E8.

SQL Server dường như bỏ qua tất cả các ký tự ngoài 36 khi thực hiện các lựa chọn của nó. Đây có phải là một lỗi / tính năng hoặc một cái gì đó có thể cấu hình?

Đó không phải là một vấn đề lớn vì chúng tôi có xác nhận ở mặt trước về chiều dài nhưng nó dường như không đúng với tôi.

Câu trả lời:


10

Chuyển đổi ngầm cũng hoạt động nếu giá trị được đặt trong dấu ngoặc nhọn {...}.

Nếu bạn thêm những người trong truy vấn, chuyển đổi ngầm định sẽ thất bại nếu giá trị ban đầu quá dài vì cuối cùng }kết thúc ở sai vị trí.

select * 
from some_table 
where uuid = '{'+'7DA26ECB-D599-4469-91D4-F9136EC0B4E8'+'}'

Nếu bạn thử chuyển đổi

SELECT CONVERT(UNIQUEIDENTIFIER, '{'+'7DA26ECB-D599-4469-91D4-F9136EC0B4E8EXTRACHARS'+'}');

bạn lấy

Msg 8169, Level 16, State 2, Line 1
Conversion failed when converting from a character string to uniqueidentifier.

10

SQL Server dường như bỏ qua tất cả các ký tự ngoài 36 khi thực hiện các lựa chọn của nó. Đây có phải là một lỗi / tính năng hoặc một cái gì đó có thể cấu hình?

Hành vi được ghi lại trong mục Sách trực tuyến cho uniqueidentifierloại :

Trích xuất BOL

Ví dụ được đề cập là:

Ví dụ BOL

Điều đó đang được nói, tôi thích tránh các chuyển đổi ngầm. Một uniqueidentifierchữ có thể được nhập trực tiếp vào T-SQL bằng cú pháp thoát ODBC:

DECLARE @T AS TABLE
(
    uuid uniqueidentifier UNIQUE NOT NULL
);

INSERT @T (uuid)
SELECT {guid '{7DA26ECB-D599-4469-91D4-F9136EC0B4E8}'};

SELECT t.uuid 
FROM @T AS t 
WHERE 
    t.uuid = {guid '{7DA26ECB-D599-4469-91D4-F9136EC0B4E8}'};

Đây là cùng một cú pháp SQL Server sử dụng nội bộ trong các kế hoạch thực hiện khi liên tục gấp một biểu diễn chuỗi thành một kiểu gõ uniqueidentifier:

SELECT t.uuid 
FROM @T AS t 
WHERE 
    t.uuid = '7DA26ECB-D599-4469-91D4-F9136EC0B4E8';

Chỉ số tìm kiếm trên uuid

Việc bạn có thể chuyển uniqueidentifiersđến và nhập từ SQL Server hay không có thể tùy thuộc vào thư viện bạn đang sử dụng, nhưng chuỗi 36 ký tự tấn công tôi là tùy chọn ít mong muốn nhất trong các tùy chọn có sẵn. Nếu bạn phải thực hiện chuyển đổi, hãy làm cho chúng rõ ràng và sử dụng giá trị nhị phân 16 byte thay vì chuỗi.


9

Các ký tự bổ sung đơn giản bị bỏ qua (tốt, âm thầm cắt ngắn) bởi SQL Server trong quá trình chuyển đổi ngầm định. Ví dụ:

SELECT CONVERT(UNIQUEIDENTIFIER, '7DA26ECB-D599-4469-91D4-F9136EC0B4E8EXTRACHARS');

Kết quả:

------------------------------------
7DA26ECB-D599-4469-91D4-F9136EC0B4E8

Điều này không giống với kịch bản này:

DECLARE @x VARCHAR(1) = 'xyz';
SELECT @x;

Kết quả:

----
x  

Bạn không thể định cấu hình điều này nhưng nếu bạn muốn biến của mình không chuyển đổi thì bạn có thể thử nhồi biến vào bảng CHAR(36)trước, điều này sẽ thất bại do cắt ngắn:

DECLARE @x TABLE(y CHAR(36));
INSERT @x SELECT '7DA26ECB-D599-4469-91D4-F9136EC0B4E8EXTRACHARS';

Kết quả:

Msg 8152, Level 16, State 14, Line 2
String or binary data would be truncated.
The statement has been terminated.
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.