解惑SQL Server中LIKE使用變量類型不同輸出結(jié)果不一致
本文轉(zhuǎn)載自微信公眾號(hào)「DBA閑思雜想錄」,作者瀟湘隱者。轉(zhuǎn)載本文請(qǐng)聯(lián)系DBA閑思雜想錄公眾號(hào)。
一同事在寫腳本時(shí),遇到一個(gè)關(guān)于LIKE里面使用不同的變量類型導(dǎo)致查詢結(jié)果不一致的問題,因?yàn)檫@個(gè)問題被不同的人問過好幾次,索性總結(jié)一下,免得每次都要解釋一遍,直接丟一篇博客豈不是更方便!其實(shí)看似有點(diǎn)讓人不解的現(xiàn)象背后實(shí)質(zhì)跟數(shù)據(jù)類型的實(shí)現(xiàn)有關(guān)。
下面我們構(gòu)造這樣一個(gè)類似的簡(jiǎn)單案例。如下所示:
- 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;
如上截圖所示,當(dāng)變量使用VARCHAR類型與CHAR類型時(shí),兩者的輸出結(jié)果完全不一樣。如果對(duì)SQL SERVER數(shù)據(jù)類型了解不透徹的話,估計(jì)真的對(duì)這個(gè)問題感到相當(dāng)?shù)睦Щ?。但是?duì)SQL Server數(shù)據(jù)類型了解比較深入的人來說,這真的是一個(gè)簡(jiǎn)單到不能再簡(jiǎn)單的問題。
如下所示,我們?cè)赟QL語句中加入兩句SQL,用DATALENGTH函數(shù)返回任何表達(dá)式的字節(jié)數(shù),你會(huì)發(fā)現(xiàn)VARCHAR類型的變量返回的字節(jié)數(shù)為3,但是CHAR類型的變量的字節(jié)數(shù)為32,其實(shí)原因就在于CHAR類型是定長(zhǎng)的,也就是當(dāng)你輸入的字符小于你指定的數(shù)目時(shí),例如char(32),你輸入的字符長(zhǎng)度小于32時(shí),它會(huì)在后面補(bǔ)空值。當(dāng)你輸入的字符長(zhǎng)度大于指定的值時(shí),它會(huì)截取超出的字符. 所以下面兩種LIKE的邏輯意義不一樣。LIKE 'ab%' 與 LIKE 'abc% '的邏輯完全不同。
其實(shí)你想從側(cè)面印證一下也很簡(jiǎn)單,如下腳本對(duì)比所示,仔細(xì)理解一下,也許你就想明白了!
- 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;