SELECT 賦值與ORDER BY沖突的問題_Mssql數(shù)據(jù)庫教程
推薦:SqlServer2005對現(xiàn)有數(shù)據(jù)進行分區(qū)具體步驟RegMail是用來存放注冊郵件的表,現(xiàn)以創(chuàng)建時間(CreateTime)字段來給表進行分區(qū),具體步驟如下: --為分區(qū)創(chuàng)建存儲文件 ALTER DATABASE Test ADD FILEGROUP RegMailFile2007 ALTER DATAB
問題描述:
使用 SELECT 語句,輪詢表中的數(shù)據(jù),并且處理變量數(shù)據(jù)時,如果有ORDER BY語句,則得不到想要的結(jié)果,但去掉ORDER BY,結(jié)果正常。
具體的問題表現(xiàn)參考下面的問題重現(xiàn)代碼
問題重現(xiàn)代碼
-- 測試數(shù)據(jù)
DECLARE @T TABLE(id int,value nvarchar(16))
INSERT INTO @T SELECT
1, N'好人' UNION ALL SELECT
2, N'壞人' UNION ALL SELECT
3, N'吃飯' UNION ALL SELECT
4, N'垃圾'
-- 賦值處理
DECLARE @str nvarchar(4000)
SET @str = N'我不是一個好人,也不是垃圾'
SELECT @str = REPLACE(@str, value, N'<u>' value N'</u>')
FROM @T
WHERE CHARINDEX(value, @str) > 0
--ORDER BY CHARINDEX(value, @str) DESC
SELECT @str
/* -- 結(jié)果(當賦值處理語句注釋掉ORDER BY 時)
我不是一個<u>好人</u>,也不是<u>垃圾</u>
-- */
/* -- 結(jié)果(當賦值處理語句加上ORDER BY 時)
我不是一個<u>好人</u>,也不是垃圾
-- */
問題分析:
兩個處理語句的結(jié)果不同,通過查看它們的執(zhí)行計劃應(yīng)該可以看出原因所在,為此,通過
SET SHOWPLAN_ALL ON
輸出了兩種執(zhí)行語句的執(zhí)行計劃(僅StmtText部分,有興趣的讀者在自己的電腦上測試的時候,可以去了解其他部分的信息)
從上面的列表可以看出,兩種處理的最大差異,在于賦值前,是否有ORDER BY 子句,從一般的理解上,可能會認為是否排序并不重要,但換個角度來看問題,就比較容易理解為什么有ORDER BY子句后得不到我們想要的結(jié)果了:
當有ORDER BY子句時,對于SELECT @str = 這種賦值處理,SQL Server認為賦值處理肯定只會保留最后一條記錄的處理結(jié)果,而ORDER BY子句確定了數(shù)據(jù)順序,也就知道最后一條記錄是那個,因此只會處理ORDER BY的最后一條記錄。(讀者可以自行去測試一下,調(diào)整ORDER BY順序,看看結(jié)果是否與我的推論相符)
當沒有ORDER BY子句時,因為無法確定數(shù)據(jù)順序,所以SQL Server必須掃描滿足條件的每條數(shù)據(jù)來得到結(jié)果,這樣每掃描一條記錄都會處理一次,所以結(jié)果是我們所預知的
問題解決方法:
修改處理語句,使查詢優(yōu)化器使用與我們需要結(jié)果一致的執(zhí)行方法,可以解決這個問題。
對于示例中的處理語句,可以調(diào)整如下:
DECLARE @str nvarchar(4000)
SET @str = N'我不是一個好人,也不是垃圾'
SELECT @str = REPLACE(@str, value, N'<u>' value N'</u>')
FROM(
SELECT TOP 100 PERCENT
value
FROM @T
WHERE CHARINDEX(value, @str) > 0
ORDER BY CHARINDEX(value, @str) DESC
)A
SELECT @str
補充:
此問題的結(jié)論只是筆者對于查詢分析的一個推論,并無相應(yīng)的官方文檔可以證明,所以歡迎大家發(fā)表自己的看法
分享:講解數(shù)據(jù)庫調(diào)優(yōu)與程序員相關(guān)的幾個方面許多程序員在面試時,經(jīng)常會被問到 “數(shù)據(jù)庫調(diào)優(yōu)”的事情,這時,許多人就會產(chǎn)生疑問,這不是DBA的事嗎,但回答不好還是顯得不夠?qū)I(yè),筆者查找了一些相關(guān)資料,發(fā)現(xiàn)許多方面還真是程
- sql 語句練習與答案
- 深入C++ string.find()函數(shù)的用法總結(jié)
- SQL Server中刪除重復數(shù)據(jù)的幾個方法
- sql刪除重復數(shù)據(jù)的詳細方法
- SQL SERVER 2000安裝教程圖文詳解
- 使用sql server management studio 2008 無法查看數(shù)據(jù)庫,提示 無法為該請求檢索數(shù)據(jù) 錯誤916解決方法
- SQLServer日志清空語句(sql2000,sql2005,sql2008)
- Sql Server 2008完全卸載方法(其他版本類似)
- sql server 2008 不允許保存更改,您所做的更改要求刪除并重新創(chuàng)建以下表
- SQL Server 2008 清空刪除日志文件(瞬間日志變幾M)
- Win7系統(tǒng)安裝MySQL5.5.21圖解教程
- 將DataTable作為存儲過程參數(shù)的用法實例詳解
Mssql數(shù)據(jù)庫教程Rss訂閱編程教程搜索
Mssql數(shù)據(jù)庫教程推薦
- 測試SQL Server業(yè)務(wù)規(guī)則鏈接方法
- 獲取SQL Server表字段的各種屬性實例代碼
- 淺談SQL Server 2008數(shù)據(jù)挖掘查詢?nèi)蝿?wù)
- sql2005 附加數(shù)據(jù)庫出錯(錯誤號:5123)解決方法
- 解析Microsoft SQL Server數(shù)據(jù)庫日志截斷
- SQL Server 游標語句 聲明/打開/循環(huán)實例
- 解讀SQL Server的BUILTIN\Administrators用戶
- 讓SQL Server數(shù)據(jù)庫自動執(zhí)行管理任務(wù)(二)
- 數(shù)據(jù)庫中兩張表之間的數(shù)據(jù)同步增加、刪除與更新實現(xiàn)思路
- SQL Server 2005 遠程調(diào)試存儲過程配置
- 相關(guān)鏈接:
- 教程說明:
Mssql數(shù)據(jù)庫教程-SELECT 賦值與ORDER BY沖突的問題
。