日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

SQL Server-聚焦深入理解动态SQL查询(三十二)

發布時間:2025/4/5 数据库 17 豆豆
生活随笔 收集整理的這篇文章主要介紹了 SQL Server-聚焦深入理解动态SQL查询(三十二) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

之前有園友一直關注著我快點出SQL Server性能優化系列,博主我也對性能優化系列也有點小期待,本來打算利用周末寫死鎖以及避免死鎖系列的接著進入SQL Server優化系列,但是在工作中長時間都是利用EF來操作SQL,不免對寫SQL語句有些生疏,在某些場景下還是只能利用底層的SQL語句或者寫存儲過程來實現,很久沒寫存儲過程都忘記怎么寫了,所以本節穿插動態SQL查詢的文章,別著急,博主說過不會爛尾,博主再忙也會抽空將整個SQL Server系列梳理完畢,那樣的話,無論對初級還是中級者都可以從中受益匪淺,至少我是這么認為,呵呵。

動態SQL語句查詢

前前篇我們簡短敘述了利用EXEC和EXECUTE來進行動態SQL語句查詢,并未深入去講解,借博主工作中重新回到寫原生SQL語句的機會,我們再來回顧下動態SQL語句查詢。既然是動態SQL查詢,說明在某些場景下利用硬編碼SQL語句查詢的方式是不可行的,比如查詢條件的不固定,這是最常見的情景,那么動態SQL語句查詢有哪幾種方式呢?萬變不離其宗,只有以下三種方式,請往下看。

參數化SQL語句動態查詢

參數化SQL查詢是動態SQL查詢中最簡單的一種,因為我們只需要傳遞參數即可,查詢條件是固定的,我們一起來溫故而知新。

USE AdventureWorks2012DECLARE @AccountNumber AS VARCHAR(200)SET @AccountNumber = 'AW00000002'SELECT StoreID, CustomerID, ModifiedDate, PersonID FROM Sales.Customer WHERE AccountNumber = @AccountNumber

EXEC動態SQL語句動態查詢?

這個相對來說比上一個要略微復雜一點,對于復雜的SQL語句拼接,我們來看看。

USE TSQL2012DECLARE @shipcity AS VARCHAR(50) DECLARE @sqlCommand AS VARCHAR(500) DECLARE @columnList AS VARCHAR(200)SET @shipcity = 'Lyon' SET @columnList = 'orderid, custid, orderdate, shipname, shipaddress, shipcity' SET @sqlCommand = 'SELECT '+ @columnList + ' FROM Sales.Orders WHERE shipcity = '+ @shipcityEXEC(@sqlCommand)

?

居然出錯了,讓人始料未及,當設置參數值時我們應該將?SET @shipcity = 'Lyon'?進行如下修改:

SET @shipcity = '''Lyon'''

sp_executesql動態SQL語句查詢(推薦)

USE TSQL2012DECLARE @shipcity AS VARCHAR(50) DECLARE @sqlCommand AS VARCHAR(500) DECLARE @columnList AS VARCHAR(200)SET @shipcity = 'Lyon' SET @columnList = 'orderid, custid, orderdate, shipname, shipaddress, shipcity' SET @sqlCommand = 'SELECT '+ @columnList + ' FROM Sales.Orders WHERE shipcity = @shipcity'EXECUTE sp_executesql @sqlCommand, N'@shipcity VARCHAR(50)', @shipcity = @shipcity

之前從未遇到過這種情況,查此錯誤居然發現要:sp_executesql執行的SQL必須定義為NVARCHAR類型即必須定義為UNICODE,這里算是學習了。

對于利用sp_executesql來執行動態sql語句查詢的方式作為推薦最主要是因為其在查詢執行計劃中,無論其變量值是否改變查詢計劃都會進行重用,當然還有其他好處,比如利用EXEC來執行查詢,此時進行拼接非常容易出錯。同時在寫動態SQL時個人一般推崇將查詢的列作為一個列表進行定義,對于參數也進行定義,這樣可維護性強不至于看起來亂糟糟的利于后續排查問題。

講到這里是不是敘述完畢了呢,那就太沒意思了,相信看過博主所寫的內容一般都是由淺入深,下面我們繼續往下看。

?一直講的動態SQL語句查詢,你難道就沒有懷疑過僅僅只能進行查詢,難道不能創建表或者創建視圖么,答案當然是可以的。我們簡單看下創建表。

Declare @SQL VarChar(1000) DECLARE @TableName AS VARCHAR(10)SET @TableName = 'Test'SELECT @SQL = 'Create Table ' + @TableName + '(' SELECT @SQL = @SQL + 'ID int NOT NULL Primary Key, FieldName VarChar(10))'Exec (@SQL)

利用EXEC或者sp_executesql居然還能創建表,還能最高級一點么,答案當然是可以,請繼續往下看。

當我們在不是當前打開會話中的數據庫中去創建另外數據庫的視圖時可行不可行呢?

Create View AdventureWorks2012.dbo.Auths AS (SELECT StoreID, CustomerID, ModifiedDate, PersonIDFROM Sales.Customerl)

此時創建視圖你會發現不能正常創建視圖,說明創建視圖必須是在當前會話指定的數據庫中才可以。

但是利用sp_executesql就能解決跨數據庫創建視圖的問題,如下:

DECLARE @SQL NVarChar(1000)SELECT @SQL = 'Create View Auths AS (SELECT CustomerID, ModifiedDate FROM Sales.Customer)'EXECUTE AdventureWorks2012.dbo.sp_executesql @sql

此時你會發現利用sp_executesql不僅可以重用查詢執行計劃并且可以跨數據庫創建視圖,那么它難道就沒有限制么,答案當然是有的,請繼續往下看。

存儲過程執行動態SQL語句查詢

當在存儲過程中執行動態SQL語句查詢時,此時動態SQL語句是在當前用戶的權限下進行而不是調用存儲過程的用戶的權限,換句話說如果我們對存儲過程上的表沒有權限,那么運行存儲過程將出現問題。還是不理解是什么意思么,也就是說存儲過程運行是有其作用域的。我們舉一個例子,我們可以利用如下語句來設置查詢的行數。

SET ROWCOUNT 3

所以接下來我們利用上述語句來查詢返回的行數。

EXEC('SET ROWCOUNT 3')SELECT * FROM Sales.CustomersEXEC('SET ROWCOUNT 0')

從上我們可以發現我們設置限制返回的行數根本不起作用,這是因為設置返回的行數已經超出了查詢的作用域。所以我們必須將其設置限制行數放到EXEC中,如下:

EXEC('SET ROWCOUNT 3 SELECT * FROM Sales.Customers SET ROWCOUNT 0')

WHERE 1 = 1問題?

對于不確定多條件篩選利用WHERE 1 = 1是否會帶來性能問題,但是除此之外似乎沒有什么好的辦法比利用WHERE 1 = 1來減少條件的判斷從而加長SQL語句,可能會導致性能的下降。下面我們來看一個簡單的例子

USE AdventureWorks2012 GO IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[Sales].[GetSalesOrders]') AND type in (N'P', N'PC')) DROP PROCEDURE [Sales].[GetSalesOrders] GOCREATE PROCEDURE [Sales].[GetSalesOrders] (@CustomerID INT = NULL,@CreditCardID INT = NULL) AS SET NOCOUNT ON; DECLARE @SQL NVARCHAR(4000); DECLARE @ParameterDefinition NVARCHAR(4000);SELECT @ParameterDefinition = ' @CustomerParameter INT,@CreditCardIDParameter INT '; SELECT @SQL = N' SELECT [SalesOrderID], [OrderDate], [Status], [CustomerID], [CreditCardID] FROM [Sales].[SalesOrderHeader] WHERE 1 = 1 '; IF @CustomerID IS NOT NULLSELECT @SQL = @SQL + N' AND CustomerID = @CustomerParameter '; IF @CreditCardID IS NOT NULLSELECT @SQL = @SQL + N' AND CreditCardID = @CreditCardIDParameter '; EXECUTE sp_executesql@SQL,@ParameterDefinition,@CustomerParameter = @CustomerID,@CreditCardIDParameter = @CreditCardID; GOSET NOCOUNT OFF;

再復雜也不過就是多表查詢和多條件篩選罷了,還是比較簡單。得出如下結果。

上述利用存儲過程創建動態SQL語句沒什么毛病。

那么問題來了,要是如果我們想調試創建過程生成的SQL語句是否有沒有錯誤,我們此時該如何做呢?為了利于調試我們可以將上述修改如下,添加一個debug標識來打印SQL。

USE AdventureWorks2012 GO IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[Sales].[GetSalesOrders]') AND type in (N'P', N'PC')) DROP PROCEDURE [Sales].[GetSalesOrders] GOCREATE PROCEDURE [Sales].[GetSalesOrders] (@CustomerID INT = NULL,@CreditCardID INT = NULL,@debug bit = 0) AS SET NOCOUNT ON; DECLARE @SQL NVARCHAR(4000); DECLARE @ParameterDefinition NVARCHAR(4000);SELECT @ParameterDefinition = ' @CustomerParameter INT,@CreditCardIDParameter INT '; SELECT @SQL = N' SELECT [SalesOrderID], [OrderDate], [Status], [CustomerID], [CreditCardID] FROM [Sales].[SalesOrderHeader] WHERE 1 = 1 '; IF @CustomerID IS NOT NULLSELECT @SQL = @SQL + N' AND CustomerID = @CustomerParameter '; IF @CreditCardID IS NOT NULLSELECT @SQL = @SQL + N' AND CreditCardID = @CreditCardIDParameter '; IF @debug = 1PRINT @SQLEXECUTE sp_executesql@SQL,@ParameterDefinition,@CustomerParameter = @CustomerID,@CreditCardIDParameter = @CreditCardID; GOEXEC [Sales].[GetSalesOrders] @debug = 1, @CustomerID = 29565SET NOCOUNT OFF;

此時我們調試發現SQL語句沒有寫錯并且生成的結果如下:

同時我們在消息中可以看到生成的SQL語句如下,這樣能夠準確無語的保證所寫動態SQL沒有問題。

總結

本節我們闡述了動態SQL以及要注意的地方,同時為了便于調試保證所生成的SQL語句不會出現問題給出的建議。下節我們開始講死鎖問題,歡迎大家持續關注博客和公眾號,對于.NET Core也會持續更新。See u!

《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀

總結

以上是生活随笔為你收集整理的SQL Server-聚焦深入理解动态SQL查询(三十二)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 免费av在线播放网址 | 国产av无毛 | 欧美日韩国产精品 | 国产精品日韩欧美一区二区三区 | 国产欧美亚洲精品 | 美女少妇一区二区 | 在线观看视频毛片 | 久久狠 | 国产稀缺精品盗摄盗拍 | 国产欧美日韩视频在线观看 | 日韩 欧美 亚洲 国产 | 天天狠狠干 | 在线免费观看黄 | 日韩爱爱网站 | 涩涩免费网站 | 中文字幕乱码人妻一区二区三区 | 欧美性猛交99久久久久99按摩 | 麻豆影视av | 精品国产不卡 | 私密视频在线观看 | 日日摸夜夜 | 一区二区三区不卡在线观看 | 欧美日韩国产一区二区 | 欧美日韩三 | 日本wwwxxxx| 色婷婷激情五月 | 日韩视频福利 | 我和单位漂亮少妇激情 | 美女视频黄频视频大全 | 天堂在线中文网 | 国产一二三区免费视频 | 久久久999久久久 | 性一交一乱一精一晶 | 日本bdsm视频| 日本一级做a爱片 | 国产精品s | 鲁一鲁啪一啪 | 97视频在线| 91n视频| 亚欧视频在线观看 | 色女生影院 | 高清av一区二区三区 | 久久精品视频8 | 蜜桃av一区二区三区 | 美乳人妻一区二区三区 | 夫妻淫语绿帽对白 | 看个毛片 | 伊人网伊人影院 | 日日摸天天添天天添破 | 全部毛片永久免费看 | 亚洲AV无码乱码国产精品色欲 | 日本不卡一区二区三区 | 亚洲天堂av免费在线观看 | 三级免费黄 | 一区二区三区波多野结衣 | 久久人人插 | 一区二区三区 中文字幕 | 成年人色片 | 亚洲美女视频在线观看 | 国产在视频线精品视频 | 97碰| 精品国产乱码久久久久久鸭王1 | 成人听书哪个软件好 | 国产在线看 | 伊人视频 | 精品国产网| 国产福利一区在线观看 | 中文字幕电影av | 一区二区免费在线视频 | 欧美啪啪小视频 | 欧美区一区二 | 国产精品老牛影视 | 91琪琪| 逼特逼在线视频 | 又大又硬又爽免费视频 | 艳妇臀荡乳欲伦交换电影 | 欧美人喂奶吃大乳 | 四川丰满少妇被弄到高潮 | 奴性白洁会所调教 | 少妇精品久久久一区二区三区 | 中文字幕久久久久久久 | 免费看一级 | 国产一级二级三级视频 | 午夜福利电影一区二区 | 国产九九精品 | 色综合久久久久综合体桃花网 | 三级免费 | 成人激情视频网 | 老汉色老汉首页av亚洲 | 狠狠干狠狠搞 | 婷婷亚洲五月色综合 | 激情网站在线观看 | 亚洲一区动漫 | 四虎黄色 | 黄色录像三级 | 可以在线看黄的网站 | 无遮挡av| 中文字幕色哟哟 | 久久久久人妻精品一区二区三区 |