テーブル値パラメータとユーザー定義テーブル型
「テーブル値パラメータ」(Table-Valued Parameters)は、Step 2.10 で説明した「ユーザー定 義テーブル型」をストゕド プロシージャの入力パラメータとして指定できる機能で、SQL Server 2008 からの新機能です。これを利用すると、IN 演算子をパラメータ化する場合に非常に便利で す。
テーブル値パラメータは、次のように利用します。
-- テーブル値パラメータ(ユーザー定義テーブル型を入力パラメータとして利用)
CREATE PROCEDURE ストアド プロシージャ名
@パラメータ名 ユーザー定義テーブル型 READONLY , …
AS
任意の Transact-SQL ステートメント
パラメータのデータ型を指定するところへユーザー定義テーブル型を指定し、READONLY(読み 取り専用)キーワードを付与して利用します。
ユーザー定義テーブル型は、Step 2.10 で説明したように table データ型のテーブル定義に対し て、名前を付けてデータ型(Type)として保存できる機能です。復習になりますが、ユーザー定 義テーブル型は、次のように利用します。
-- ユーザー定義テーブル型
CREATE TYPE 型名
AS TABLE
( 列名 データ型
,列名 データ型 , … )go
-- ユーザー定義テーブル型の利用
DECLARE @変数名 型名
Let's Try
それでは、テーブル値パラメータを利用して、IN 演算子をパラメータ化してみましょう。
1. まずは、IN 演算子へ与える値を格納するための int データ型の列を持ったユーザー定義テー ブル型を「valuelist」という名前で作成します。
-- ユーザー定義テーブル型
CREATE TYPE valuelist
AS TABLE ( val int ) go2. 次にテーブル値パラメータを利用して、ストゕド プロシージャを作成します。
-- テーブル値パラメータを利用するストアド プロシージャ
CREATE PROCEDURE proc3
@v valuelist READONLY
AS
SELECT * FROM emp
WHERE empno IN ( SELECT val FROM @v )
IN 演算子の部分をサブクエリとし、@v(ユーザー定義テーブル型 valuelist を指定したパ ラメータ)から val 列(int データ型の列)を取得して、それを IN 演算子へ与えています。
3. 次に、ユーザー定義テーブル型の val 列へ「1」と「5」を格納して、この値をストゕド プロ シージャのパラメータへ与えてみます。
-- ユーザー定義テーブル型を利用した変数@v の宣言
DECLARE @v AS valuelist
-- 変数 @v へ値の格納(IN 演算子に与える値)
INSERT INTO @v (val)
VALUES ( 1 ),( 5 )
-- ストアド プロシージャの実行
EXEC proc3 @v
empno が 1 と 5 の社員を取得できていることを確認できます。
このように、ユーザー定義テーブル型とテーブル値パラメータを利用すると、IN 演算子のパ ラメータ化が簡単に行えるようになります。
Tips: ADO.NET からテーブル値パラメータを利用する場合
VB や C# などのゕプリケーションからテーブル値パラメータへ値を利用する場合は、SqlParameter クラスの データ型として「Structured」を指定して、DataTable クラスへ値を格納しておくようにします。具体的には 次のように利用します(VB の場合)。
Imports System.Data
Imports System.Data.SqlClient Imports System.Data.SqlTypes
:
' DataTable オブジェクトへ値を格納 Dim dt As New DataTable
Dim row As DataRow
dt.Columns.Add("val", Type.GetType("System.Int32"))
' val 列へ 1 を格納
row = dt.NewRow() row("val") = 1 dt.Rows.Add(row)
' val 列へ 5 を格納
row = dt.NewRow() row("val") = 5 dt.Rows.Add(row)
Dim cnstr As String = "Server=localhost;Database=sampleDB;Integrated Security=SSPI"
Using cn As SqlConnection = New SqlConnection(cnstr)
cn.Open()
Using cmd As SqlCommand = New SqlCommand() cmd.Connection = cn
cmd.CommandType = CommandType.StoredProcedure cmd.CommandText = "proc3"
' SqlParameter のデータ型へ Structured を指定
Dim p1 As SqlParameter = cmd.Parameters.AddWithValue("@v", SqlDbType.Structured) p1.TypeName = "valuelist"
p1.Value = dt
Using dr As SqlDataReader = cmd.ExecuteReader() While dr.Read()
Debug.Print(dr("empno") & vbTab & dr("empname")) End While
End Using End Using
End Usingempno が 1 と 5 の 社員を取得