SQL SERVER 重組含有特殊字符的索引時遇到“關鍵字 'with' 附近有語法錯誤.”


案例描述

    這是在索引重組過程中遇到的有意思的錯誤案例,搜索了一下也沒有看到相關資料,估計我第一個碰到這類錯誤的人(It's just a joke)。具體情況是YourSQLDba在做維護數據庫索引時遇到了索引重組錯誤,然后我排查時就發現了這個案例。我下面用一個簡單的測試例子演示一下具體情況。

 

數據庫版本: SQL SERVER 2005

CREATE TABLE TEST
 
(
 
 ID     INT,
 
 Name   VARCHAR(12)
 
);
 
CREATE NONCLUSTERED INDEX "[IDX_NAME]" ON TEST(Name);
 

 

因為YourSQLDba生成重組索引語句時,都會在索引名稱上加上[].如果用下面SQL語句進行索引重組,就會遇到這個錯誤

ALTER INDEX [[IDX_NAME]] ON [dbo].[TEST]

Reorganize With (LOB_COMPACTION = On);

消息 102,級別 15,狀態 1,第 1 行

'.' 附近有語法錯誤。

消息 319,級別 15,狀態 1,第 2 行

關鍵字 'with' 附近有語法錯誤。如果此語句是公用表表達式或 xmlnamespaces 子句,那么前一個語句必須以分號結尾。

clipboard

我們嘗試去掉一對[],此時就會報"找不到索引'IDX_NAME'"的錯誤。其實這個好理解,因為雙引號被解釋為字符串的邊界,所以[IDX_NAME]才是真正的索引名稱,但是如果你重建索引時使用[IDX_NAME], 那么[]就變成了解釋字符邊界的字符,索引名就成了IDX_NAME,顯然就會出現找不到該索引的錯誤提示。

ALTER INDEX [IDX_NAME] ON [dbo].[TEST]
 
Reorganize With (LOB_COMPACTION = On);
 

clipboard[1]

消息 2727,級別 11,狀態 1,第 2 行

找不到索引 'IDX_NAME'。

如果在索引名稱上加上"",那么索引名就成了[IDX_NAME], 那么此時就可以成功進行索引重建。這兩者都好理解。

ALTER INDEX "[IDX_NAME]" ON [dbo].[TEST]
 
Reorganize With (LOB_COMPACTION = On);
 

clipboard[2]

而使用[[IDX_NAME]]這種寫法時,並不能完全讓數據庫引擎知道索引名為[IDX_NAME],有可能是語義解析時就有問題,這個我們也能理解,但是如果在MSSMS窗口將索引拖到查詢窗口,你會驚奇的發現索引名變成了[[IDX_NAME]]]這個鳥樣,不清楚為什么這樣。這樣的SQL進行索引重組也是成功的。

clipboard[3]

在SQL Server 2008下面測試,發現報錯的提示有些不一樣。如下所示:

clipboard[4]

 

當然測試過程中要求設置SET QUOTED_IDENTIFIER的值為ON,關於SET QUOTED_IDENTIFIER的設置為:

     當SET QUOTED_IDENTIFIER值為ON時,雙引號內的字符被當作是數據庫對象。就是說雙引號" "和標識符[]效果是一樣樣的,他們都表示引用的字符是數據庫對象。單引號'表示字符串的邊界。

     當SET QUOTDE_IDENTIFIER OFF時,雙引號被解釋為字符串的邊界,和單引號的作用是類似的。就是說雙引號"不能當做標識符使用,但是可以當做字符邊界,和單引號'的效果是一樣樣的。

 

解決方法:

    既然搞清楚了原因,那么就很容易解決問題了。刪除索引后,然后重建索引時取消雙引號以及[]就OK了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM