詳細瞭解SQL Server 2008效能和效能優化
在SQL Server 2005或更早的版本中的資料庫中,表變數是不能作為儲存過程的引數的。當多行資料到SQL Server需要傳送多行資料到SQL Server ,開發者要麼每次傳送一列記錄,或想出其他的變通方法,以滿足需求。雖然在.net 2.0中提供了個SQLBulkCopy物件能夠將多個資料行一次性傳送給SQL Server,但是多行資料仍然無法一次性傳給儲存過程。
SQL Server 2008中的T-SQL功能新增了表值引數。利用這個新增特性,我們可以很方便地通過T-SQL語句,或者通過一個應用程式,將一個表作為引數傳給儲存過程。
1、使用者自定義表型別
當第一次看看新的表值引數,我認為使用此功能有點複雜。有幾個步驟。要做的第一件事是定義表型。在Management Studio 2008中的“Programmability”“Type”節點,您可以看到“User-Defined Table Types(使用者自定義表型別)”,如圖1所示 。
圖 1:使用者自定義表型別
點選右鍵,在彈出選單中選擇“新使用者定義的表型... ” ,會新建一個模板中的查詢視窗,如圖2所示 。
圖2:使用者自定義表型別建立語句
點選“Specify Values for Template Parameters(指定值為模板引數)”按鈕,將探出一個對話方塊,如圖3所示。
圖 3:指定模板引數列的數值
在填寫在適當的數值之後,點選確定按鈕,一個“CREATE TYPE”的宣告取代了範本。這時,你也可以手動增加一些列,或者增加一些限制條件,最後點選確定按鈕。
以下是最終的程式碼:
-- ================================ -- Create User-defined Table Type -- ================================ USE Test GO -- Create the data type CREATE TYPE dbo.MyType AS TABLE ( col1 int NOT NULL, col2 varchar(20) NULL, col3 datetime NULL, PRIMARY KEY (col1) ) GO |
在執行程式碼之後,物件的定義就建立好了,你可以在“User-Defined Table Type(使用者自定義表型別”中檢視屬性,如圖4所示,但沒法修改它們。如果要修改的型別,你只能將其刪除,然後按照修改後的屬性再次建立它。
圖4:檢視使用者自定義表型別的屬性
2、使用使用者自定義的表型別
如果打算在T-SQL程式碼中使用,您還必須建立一個新型別的變數,然後將具體的表的名稱賦值給該變數。一旦賦值後,您可以在其他的T-SQL語句中使用它。因為它是一個變數,在批處理完成後,它也自動失效,結束生命週期。
請注意下面的程式碼,MyType是我們之前剛剛建立的資料型別。
DECLARE @MyTable MyType INSERT INTO @MyTable(col1,col2,col3) VALUES (1,'abc','1/1/2000'), (2,'def','1/1/2001'), (3,'ghi','1/1/2002'), (4,'jkl','1/1/2003'), (5,'mno','1/1/2004') SELECT * FROM @MyTable |
在變數的有效範圍內,你可以象操作正常的表一樣來操作這個變數,如與另一個表象關聯或者將變數中的記錄填充到另一個表。對於表變數來說,你無法修改表定義。
正如前面提到的,變數不能超出它的有效的範圍。如果T-SQL指令碼由多個批處理組成,變數只有在批處理內才能建立並有效使用。
3、使用變數作為引數
到目前為止,我們還沒有看到經常表變數無法實現的功能。其好處是能夠將變數作為引數傳給儲存過程。當然一個儲存過程必須先建立,使用新的型別作為其中的一個引數。
下面這個例子,通過程式碼建立一個常規表,並對其填充記錄。
USE [Test] GO CREATE TABLE [dbo].[MyTable] ( [col1] [int] NOT NULL PRIMARY KEY, [col2] [varchar](20) NULL, [col3] [datetime] NULL, [UserID] [varchar] (20) NOT NULL ) GO CREATE PROC usp_AddRowsToMyTable @MyTableParam MyType READONLY, @UserID varchar(20) AS INSERT INTO MyTable([col1],[col2],[col3],[UserID]) SELECT [col1],[col2],[col3],@UserID FROM @MyTableParam GO |
請注意表值引數後面帶了個READONLY引數。這是必需的,不能在例程體中對錶值引數執行諸如 UPDATE、DELETE 或 INSERT 這樣的 DML 操作。
最後,我們對建立表值變數,對變數進行賦值,並呼叫儲存過程。
DECLARE @MyTable MyType INSERT INTO @MyTable(col1,col2,col3) VALUES (1,'abc','1/1/2000'), (2,'def','1/1/2001'), (3,'ghi','1/1/2002'), (4,'jkl','1/1/2003'), (5,'mno','1/1/2004') EXEC usp_AddRowsToMyTable @MyTableParam = @MyTable, @UserID = 'Kathi' SELECT * FROM MyTable |
為了讓使用者使用自定義表型別,執行或控制許可權必須是理所當然的。以下是授權命令:
GRANT EXECUTE ON TYPE::dbo.MyType TO TestUser; |
4、通過.net應用程式呼叫
表值引數這一特性最大的亮點在於可以在.net應用中使用表值引數。為了做到這一點,你必須要先安裝.NET 3.5框架,並確保應用程式中已經引用了 System.Data.SqlClient名稱空間。建立表值引數時需要用到一些新的SQL資料型別(如DataTable、DataColumn等)。
首先建立一個本地資料表,並插入一些記錄。肯定的是, DataTable中建立符合使用者定義的表型的列計數和資料型別。
'Create a local table Dim table As New DataTable("temp") Dim col1 As New DataColumn("col1", System.Type.GetType("System.Int32")) Dim col2 As New DataColumn("col2", System.Type.GetType("System.String")) Dim col3 As New DataColumn("col3", System.Type.GetType("System.DateTime")) table.Columns.Add(col1) table.Columns.Add(col2) table.Columns.Add(col3) 'Populate the table For i As Integer = 20 To 30 Dim vals(2) As Object vals(0) = i vals(1) = Chr(i + 90) vals(2) = System.DateTime.Now table.Rows.Add(vals) Next |
我們在程式碼中採用儲存過程:建立一個命令物件,並新增兩個引數。程式碼如下圖所示:
'Create a command object that calls the stored proc Dim command As New SqlCommand("usp_AddRowsToMyTable", conn) command.CommandType = CommandType.StoredProcedure 'Create a parameter using the new type Dim param As SqlParameter = command.Parameters.Add ("@MyTableParam", SqlDbType.Structured) command.Parameters.AddWithValue("@UserID", "Kathi") |
請注意@ MyTableParam引數的資料型別(SqlDbType.Structured),這是.Net 3.5中新增的功能。最後,將當地表賦值給表值引數,並執行該命令。
'Set the value of the parameter param.Value = table 'Execute the query command.ExecuteNonQuery() |
5、小結
SQL Server 2008中新增的表值引數特性,減少了應用程式與SQL Server資料庫伺服器之間的互動,提升了程式效能。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/16436858/viewspace-515940/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 帶你詳細解讀十條關於SQL效能優化!SQL優化
- 詳解SQL效能優化十條經驗SQL優化
- Oracle 高效能SQL引擎剖析--SQL優化與調優機制詳解OracleSQL優化
- SQL效能優化技巧SQL優化
- sql語句效能優化SQL優化
- (iOS) UICollectionViewLayoutInvalidationContext效能優化 詳細流程圖 + 範例iOSUIViewContext優化流程圖
- Oracle效能優化-SQL優化(案例一)Oracle優化SQL
- Oracle效能優化-SQL優化(案例二)Oracle優化SQL
- Oracle效能優化-SQL優化(案例三)Oracle優化SQL
- Oracle效能優化-SQL優化(案例四)Oracle優化SQL
- 效能調優——SQL最佳化SQL
- android效能調優詳解Android
- SQL Server 2008中Analysis Services的新特性——深入SQL Server 2008SQLServer
- MySQL的SQL效能優化總結MySql優化
- 【前端效能優化】vue效能優化前端優化Vue
- Spark 3.x Spark Core詳解 & 效能優化Spark優化
- React效能優化的8種方式瞭解一下?React優化
- SQL SERVER優化SQLServer優化
- TensorFlow 1.9迎來優化版,詳細效能更新干貨分享!優化
- SQL SERVER 2008安全配置SQLServer
- 瞭解GaussDB效能調優之隱式轉換,解決慢SQL問題SQL
- SQL Server 資料庫 最佳化 效能瓶頸SQLServer資料庫
- SQL效能第1篇:關係優化SQL優化
- 深入瞭解 TiDB SQL 優化器TiDBSQL優化
- 資料庫效能優化-索引與sql相關優化資料庫優化索引SQL
- 神奇的 SQL 之效能優化 → 讓 SQL 飛起來SQL優化
- 效能優化優化
- 高效能渲染——詳解Html Canvas的優勢與效能HTMLCanvas
- 效能調優-Mysql索引資料結構詳解與索引優化MySql索引資料結構優化
- MySQL效能優化之簡單sql改寫MySql優化
- Oracle SQL效能優化的40條軍規OracleSQL優化
- SQL Server 2005效能調整一(zt)SQLServer
- SQL Server 2005效能調整二(zt)SQLServer
- 深入瞭解HTTP/2的前世今生以及Web效能優化總結HTTPWeb優化
- Django ORM效能優化之count和len方法的選擇(非常詳細推薦乾貨)DjangoORM優化
- MySQL-效能優化-索引和查詢優化MySql優化索引
- MySQL 52個SQL效能優化策略SQL語句彙總MySql優化
- 測量、基線和效能優化之二:基線和效能優化
- 你真的瞭解“SQL”嗎?《SQL優化最佳實踐》作者帶你重新瞭解SQLSQL優化