一同事在寫腳本時,遇到一個關於LIKE裡面使用不同的變數類型導致查詢結果不一致的問題,因為這個問題被不同的人問過好幾次,索性總結一下,免得每次都要解釋一遍,直接丟一篇博客豈不是更方便!其實看似有點讓人不解的現象背後實質跟數據類型的實現有關。 下麵我們構造這樣一個類似的簡單案例。如下所, CREATE... ...
一同事在寫腳本時,遇到一個關於LIKE裡面使用不同的變數類型導致查詢結果不一致的問題,因為這個問題被不同的人問過好幾次,索性總結一下,免得每次都要解釋一遍,直接丟一篇博客豈不是更方便!其實看似有點讓人不解的現象背後實質跟數據類型的實現有關。
下麵我們構造這樣一個類似的簡單案例。如下所,
CREATE TABLE TEST
(ID INT IDENTITY(1,1),
NAME VARCHAR(32)
)
INSERT INTO dbo.test
SELECT 'abc32'
INSERT INTO dbo.test
SELECT 'abd32'
INSERT INTO dbo.test
SELECT 'abe32'
DECLARE @name VARCHAR(32);
SET @name='ab%';
SELECT * FROM TEST WHERE NAME LIKE @name;
DECLARE @name1 CHAR(32);
SET @name1='ab%';
SELECT * FROM dbo.TEST WHERE NAME LIKE @name1;
如上截圖所示,當變數使用VARCHAR類型與CHAR類型時,兩種的輸出結果完全不一樣。如果對SQL SERVER數據類型瞭解不透徹的話,估計真的對這個問題感到相當困惑。但是對SQL Server數據類型瞭解比較深入的人來說,這真的是一個簡單到不能再簡單的問題。
如下所示,我們在SQL語句中加入兩句SQL,用DATALENGTH返回任何表達式的位元組數,你會發現VARCHAR類型的變數返回的位元組數為3,但是CHAR類型的變數的位元組數為32,其實原因就在於CHAR類型是定長的,也就是當你輸入的字元小於你指定的數目時,例如char(32),你輸入的字元小於32時,它會在後面補空值。當你輸入的字元大於指定的數時,它會截取超出的字元. 所以下麵兩種LIKE的邏輯意義不一樣。LIKE 'ab%' 與 LIKE 'abc% '的邏輯完全不同。
其實你想從側面印證一下也很簡單,如下腳本對比所示,仔細理解一下,也許你就想明白了!
DECLARE @name CHAR(32);
SET @name='ab%';
SELECT * FROM TEST WHERE NAME LIKE @name;
DECLARE @name1 CHAR(3);
SET @name1='ab%';
SELECT * FROM dbo.TEST WHERE NAME LIKE @name1;