解惑SQL Server中LIKE使用變量類型不同輸出結果不一致
本文轉載自微信公眾號「DBA閑思雜想錄」,作者瀟湘隱者。轉載本文請聯系DBA閑思雜想錄公眾號。
一同事在寫腳本時,遇到一個關于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;