Унікальний ідентифікатор із додатковими символами, які все ще відповідають Вибору


19

Ми використовуємо SQL Server 2012 з унікальним ідентифікатором, і ми помітили, що при виборі додаткових символів, доданих до кінця (так що не 36 символів), він все одно повертає відповідність UUID.

Наприклад:

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

повертає рядок з uuid 7DA26ECB-D599-4469-91D4-F9136EC0B4E8.

Але якщо ви запускаєте:

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

він також повертає рядок з uuid 7DA26ECB-D599-4469-91D4-F9136EC0B4E8.

Здається, SQL Server ігнорує всі символи за межами 36, виконуючи його вибір. Це помилка / функція чи щось, що можна налаштувати?

Це не є масовим питанням, оскільки ми маємо перевірку на передньому кінці на довжину, але це не здається мені правильною поведінкою.

Відповіді:


10

Неявна конверсія також працює, якщо значення укладено у фігурні дужки {...}.

Якщо ви додаєте ці запити, неявна конверсія не вдасться, якщо початкове значення занадто довге, оскільки останнє }закінчується в неправильному місці.

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

Якщо ви спробуєте конвертувати

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

Ви отримуєте

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

10

Здається, SQL Server ігнорує всі символи за межами 36, виконуючи його вибір. Це помилка / функція чи щось, що можна налаштувати?

Поведінка задокументована у статті "Книги онлайн" uniqueidentifierтипу :

Виписка BOL

Наведений приклад:

Приклад BOL

Якщо говорити, я вважаю за краще уникати неявних перетворень. uniqueidentifierБуквальний можна вводити безпосередньо в T-SQL , використовуючи синтаксис 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}'};

Це той самий синтаксис, який SQL Server використовує внутрішньо в планах виконання при постійному складенні подання рядка на введений uniqueidentifier:

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

Індекс шукайте на uuid

Чи ви можете передати набраний uniqueidentifiersна SQL Server і з нього, може залежати від бібліотеки, яку ви використовуєте, але рядки з 36 символів вважають мене найменш бажаним із доступних параметрів. Якщо потрібно здійснити перетворення, зробіть їх явними та використовуйте 16-байтове двійкове значення замість рядка.


9

Додаткові символи просто ігноруються (ну, мовчки усікаються) під час неявного перетворення. Наприклад:

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

Результат:

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

Це не на відміну від цього сценарію:

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

Результат:

----
x  

Ви не можете налаштувати це, але якщо ви хочете, щоб ваша змінна не вдалася до конверсії, тоді ви можете спробувати ввести змінну в таблицю CHAR(36)спочатку, яка не вдасться через усічення:

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

Результат:

Msg 8152, Level 16, State 14, Line 2
String or binary data would be truncated.
The statement has been terminated.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.