Pengidentifikasi Unik dengan Karakter Ekstra Masih Cocok di Pilih

19

Kami menggunakan SQL Server 2012 dengan pengidentifikasi unik dan kami perhatikan bahwa ketika melakukan seleksi dengan karakter tambahan ditambahkan ke akhir (jadi bukan 36 karakter), ia masih mengembalikan kecocokan ke UUID.

Sebagai contoh:

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

mengembalikan baris dengan uuid 7DA26ECB-D599-4469-91D4-F9136EC0B4E8.

Tetapi jika Anda menjalankan:

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

itu juga mengembalikan baris dengan uuid 7DA26ECB-D599-4469-91D4-F9136EC0B4E8.

SQL Server tampaknya mengabaikan semua karakter di luar 36 ketika melakukan pemilihannya. Apakah ini bug / fitur atau sesuatu yang dapat dikonfigurasi?

Ini bukan masalah besar karena kami memiliki validasi di ujung depan untuk panjang tapi itu kelihatannya tidak benar untuk saya.

Chris Jones - Belgia
sumber

Jawaban:

10

Konversi implisit juga berfungsi jika nilainya tertutup kurung keriting {...}.

Jika Anda menambahkan mereka di kueri konversi implisit akan gagal jika nilai aslinya terlalu panjang karena yang terakhir }berakhir di tempat yang salah.

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

Jika Anda mencoba konversi

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

Anda mendapatkan

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

SQL Server tampaknya mengabaikan semua karakter di luar 36 ketika melakukan pemilihannya. Apakah ini bug / fitur atau sesuatu yang dapat dikonfigurasi?

Perilaku ini didokumentasikan dalam entri Books Online untuk uniqueidentifierjenis :

Ekstrak entri BOL

Contoh yang dimaksud adalah:

Contoh BOL

Yang sedang berkata, saya lebih suka untuk menghindari konversi implisit. Sebuah uniqueidentifierliteral dapat diketik langsung di T-SQL menggunakan sintaks ODBC melarikan diri:

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}'};

Ini adalah sintaks yang sama yang digunakan SQL Server secara internal dalam rencana eksekusi ketika melipat-kan representasi string secara konstan menjadi uniqueidentifier:

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

Pencarian indeks pada uuid

Apakah Anda dapat meneruskan mengetik uniqueidentifierske dan dari SQL Server mungkin tergantung pada perpustakaan yang Anda gunakan, tetapi string 36-karakter menurut saya sebagai pilihan yang paling tidak diinginkan dari opsi yang tersedia. Jika Anda harus melakukan konversi, buatlah eksplisit, dan gunakan nilai biner 16 byte sebagai ganti string.

Paul White mengatakan GoFundMonica
sumber
9

Karakter tambahan hanya diabaikan (baik, diam-diam terpotong) oleh SQL Server selama konversi implisit. Sebagai contoh:

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

Hasil:

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

Ini tidak berbeda dengan skenario ini:

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

Hasil:

----
x  

Anda tidak dapat mengonfigurasi ini tetapi jika Anda ingin variabel Anda gagal konversi maka Anda dapat mencoba memasukkan variabel ke dalam tabel CHAR(36)terlebih dahulu, yang akan gagal karena pemotongan:

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

Hasil:

Msg 8152, Level 16, State 14, Line 2
String or binary data would be truncated.
The statement has been terminated.
Aaron Bertrand
sumber