実際のデータベースアプリケーションは、あらゆる種類の機能を実行するために、フロントエンドからデータベースに対して複数の要求を行う必要があります。
銀行や空港などで使用されるようなアプリケーションがデータ集約型である場合、データトリップの数は膨大になる可能性があります。データベースへの各リクエストは帯域幅を利用し、実行に時間がかかります。テーブル値パラメーターがない場合、フロントアプリケーションは、データの複数の行を操作するために複数のデータトリップを行う必要があります。ただし、テーブル値パラメーターを使用すると、テーブル値パラメーターを受け取る単一のパラメーター化されたコマンドを使用して、データベースに複数の行を挿入、更新、およびデータベースから削除できます。
テーブル値パラメーターは、テーブルタイプのパラメーターです。このパラメーターを使用すると、複数行のデータをストアード・プロシージャーまたはパラメーター化されたSQLコマンドに表形式で送信できます。 Transact-SQLを使用して、テーブル値パラメーターの列値にアクセスできます。
この記事では、データテーブルをストアドプロシージャに渡す方法を学習します。ただし、その前に、表形式のデータがテーブル値パラメーターの前にどのように渡されたかを見てみましょう。
テーブル値パラメーターの前に表形式でデータを渡す
表値パラメーターはSQLServer2008で導入されました。それ以前は、表形式のデータをストアドプロシージャに渡すためのオプションが制限されていました。ほとんどの開発者は、次のいずれかの方法を使用しました。
- 複数の列と行のデータは、一連のパラメーターの形式で表されました。ただし、SQLServerストアドプロシージャに渡すことができるパラメータの最大数は2,100です。したがって、大きなテーブルの場合、この方法は使用できませんでした。さらに、個々のパラメータを表形式にフォーマットするには、サーバー側で前処理が必要です。
- UPDATEなど、複数の行に影響を与える可能性のある複数のSQLステートメントを作成します。ステートメントは、個別に、またはバッチ形式でサーバーに送信できます。バッチ形式で送信された場合でも、ステートメントはサーバー上で個別に実行されます。
- もう1つの方法は、区切り文字列またはXMLドキュメントを使用して、複数の行と列のデータをバンドルし、これらのテキスト値をパラメーター化されたSQLステートメントまたはストアドプロシージャに渡すことです。このアプローチの欠点は、値をバンドル解除するためにデータ構造を検証する必要があることでした。
データテーブルをパラメータとしてストアドプロシージャに渡す
次に、前のセクションで説明した問題に直面することなく、テーブル値パラメーターを使用してデータをストアドプロシージャに送信する方法を見てみましょう。テーブル値パラメーターを使用すると、Transact-SQLコードまたはフロントエンドアプリケーションから複数行のデータをストアドプロシージャに渡すことができます。テーブル値パラメータが持つことができる最大サイズは、データベースサーバーの最大メモリサイズと同じです。
このセクションでは、テーブル値パラメーターとストアドプロシージャを使用して、データテーブルに複数の行を挿入します。
テーブル値パラメーターをストアード・プロシージャーに渡すことは、3つのステップのプロセスです。
- 入力するテーブルに対応するユーザー定義のテーブルタイプを作成します。
- ユーザー定義テーブルをパラメータとしてストアドプロシージャに渡します
- ストアドプロシージャ内で、渡されたパラメータからデータを選択し、データを入力するテーブルに挿入します。
テーブル値関数を使用してデータテーブルをストアドプロシージャに渡す方法の例を見てみましょう。
まず、入力するテーブルを作成します。次のスクリプトを実行します。
CREATE DATABASE ShowRoom USE ShowRoom Create Table Cars ( Id int primary key, Name nvarchar(50), company nvarchar(50) ) Go
上記のスクリプトでは、1つのテーブル(Cars)を使用してShowRoomというデータベースを作成します。 Carsテーブルには、Id、Name、およびcompanyの3つの列があります。ストアドプロシージャを使用してCarsテーブルにデータを入力します。
前に説明したように、最初のステップは、入力するテーブルに対応するユーザー定義のテーブルタイプを作成することです。これを行うには、次のスクリプトを実行します。
CREATE TYPE CarTableType AS TABLE ( Id int primary key, Name nvarchar(50), company nvarchar(50) ) Go
上記のスクリプトでは、テーブルタイプのCarTableTypeユーザー定義変数を作成します。これは、ストアドプロシージャに渡す変数です。 CarTableType変数の列がCarsテーブルの列と類似していることがわかります。
次に、CarTableType変数をパラメーターとして受け入れるストアドプロシージャを作成しましょう。ストアドプロシージャ内で、この変数からすべてのレコードを選択し、Carsテーブルに挿入します。次のスクリプトを実行して、このようなストアドプロシージャを作成します。
CREATE PROCEDURE spInsertCars @CarType CarTableType READONLY AS BEGIN INSERT INTO Cars SELECT * FROM @CarType END
上記のスクリプトでは、spInsertCarsストアドプロシージャを作成します。ストアドプロシージャ内でユーザー定義パラメーターをREADONLYとして指定する必要があることに注意してください。指定しないと、ランタイムエラーが発生します。
spInsertCarsストアドプロシージャがCarTableTypeパラメータを受け入れ、それをCarTableTypeタイプの@CarType変数に割り当てていることがわかります。
最後のステップは、CarTableType変数の変数を作成し、ダミーデータを入力して、spInsertCarsストアドプロシージャに渡すことです。次のスクリプトを見てください:
DECLARE @CarTableType CarTableType INSERT INTO @CarTableType VALUES (1, 'Corrolla', 'Toyota') INSERT INTO @CarTableType VALUES (2, 'Civic', 'Honda') INSERT INTO @CarTableType VALUES (3, '6', 'Audi') INSERT INTO @CarTableType VALUES (4, 'c100', 'Mercedez') INSERT INTO @CarTableType VALUES (5, 'Mustang', 'Ford') EXECUTE spInsertCars @CarTableType
上記のスクリプトでは、最初にタイプCarTableTypeの@CarTableType変数を宣言します。次に、この変数に5つのダミーレコードを挿入します。最後に、spInsertCarsストアドプロシージャを実行し、@CarTableType変数をパラメータとして渡します。
ストアドプロシージャ内で、@ CarTableType変数から5つのレコードが選択され、Carsテーブルに挿入されます。ここで、Carsテーブルからすべてのレコードを選択すると、新しく挿入されたレコードが表示されます。これを行うには、次のスクリプトを実行します。
SELECT * FROM Cars
上記のスクリプトの出力は次のようになります:
出力から、@CarTableType変数のすべてのレコードがCarsテーブルに挿入されていることがわかります。