ユーザー定義型へのアクセス - UDT データの取得
適用対象: SQL Server
クライアントでユーザー定義型 (UDT) を作成するには、SQL Server データベースに UDT として登録されたアセンブリをクライアント アプリケーションで使用できる必要があります。 この UDT アセンブリは、アプリケーションと同じディレクトリまたは GAC (グローバル アセンブリ キャッシュ) に配置できます。 また、プロジェクト内で、このアセンブリへの参照を設定することもできます。
ADO.NET で UDT を使用するための要件
クライアントで UDT を作成するには、SQL Server に読み込まれたアセンブリとクライアント上のアセンブリに互換性がある必要があります。 Native シリアル化形式で定義された UDT の場合、アセンブリは構造的に互換性がある必要があります。 UserDefined 形式で定義されたアセンブリの場合、アセンブリはクライアントで使用できる必要があります。
テーブルの UDT 列からデータをそのまま取得するために、クライアントに UDT アセンブリをコピーする必要はありません。
Note
SQLClient は、UDT のバージョンが一致しない場合やその他の問題が発生した場合に、UDT の読み込みに失敗する可能性があります。 この場合、通常のトラブルシューティング メカニズムを使用して、呼び出し元のアプリケーションで UDT を含むアセンブリが検出されない原因を特定します。 詳細については、.NET Framework のドキュメントのトピック「マネージド デバッグ アシスタントによるエラーの診断」を参照してください。
SqlDataReader による UDT へのアクセス
System.Data.SqlClient.SqlDataReader をクライアント コードから使用して、オブジェクトのインスタンスとして公開される UDT 列を含む結果セットを取得できます。
例
この例では、 Main メソッドを使用して、新しい SqlDataReader オブジェクトを作成する方法を示します。 このコード例では、次の操作が行われます。
Main メソッドは、新しい SqlDataReader オブジェクトを作成し、Point という名前の UDT 列を持つ Points テーブルから値を取得します。
Point UDT では、整数型として定義されている X 座標と Y 座標が公開されます。
UDT は、 Distance メソッドと GetDistanceFromXY メソッドを定義します。
このサンプル コードでは、UDT の機能を例示するために主キーと UDT 列の値を取得します。
このサンプル コードは、 Point.Distance および Point.GetDistanceFromXY メソッドを呼び出します。
結果はコンソール ウィンドウに表示されます。
Note
アプリケーションでは、事前に UDT アセンブリへの参照が設定されている必要があります。
Option Explicit On
Option Strict On
Imports System
Imports System.Data.Sql
Imports System.Data.SqlClient
Module ReadPoints
Sub Main()
Dim connectionString As String = GetConnectionString()
Using cnn As New SqlConnection(connectionString)
cnn.Open()
Dim cmd As New SqlCommand( _
"SELECT ID, Pnt FROM dbo.Points", cnn)
Dim rdr As SqlDataReader
rdr = cmd.ExecuteReader
While rdr.Read()
' Retrieve the value of the Primary Key column
Dim id As Int32 = rdr.GetInt32(0)
' Retrieve the value of the UDT
Dim pnt As Point = CType(rdr(1), Point)
' You can also use GetSqlValue and GetValue
' Dim pnt As Point = CType(rdr.GetSqlValue(1), Point)
' Dim pnt As Point = CType(rdr.GetValue(1), Point)
' Print values
Console.WriteLine( _
"ID={0} Point={1} X={2} Y={3} DistanceFromXY={4} Distance={5}", _
id, pnt, pnt.X, pnt.Y, pnt.DistanceFromXY(1, 9), pnt.Distance())
End While
rdr.Close()
Console.WriteLine("done")
End Using
End Sub
Private Function GetConnectionString() As String
' To avoid storing the connection string in your code,
' you can retrieve it from a configuration file.
Return "Data Source=(local);Initial Catalog=AdventureWorks;" _
& "Integrated Security=SSPI;"
End Function
End Module
using System;
using System.Data.Sql;
using System.Data.SqlClient;
namespace Microsoft.Samples.SqlServer
{
class ReadPoints
{
static void Main()
{
string connectionString = GetConnectionString();
using (SqlConnection cnn = new SqlConnection(connectionString))
{
cnn.Open();
SqlCommand cmd = new SqlCommand(
"SELECT ID, Pnt FROM dbo.Points", cnn);
SqlDataReader rdr = cmd.ExecuteReader();
while (rdr.Read())
{
// Retrieve the value of the Primary Key column
int id = rdr.GetInt32(0);
// Retrieve the value of the UDT
Point pnt = (Point)rdr[1];
// You can also use GetSqlValue and GetValue
// Point pnt = (Point)rdr.GetSqlValue(1);
// Point pnt = (Point)rdr.GetValue(1);
Console.WriteLine(
"ID={0} Point={1} X={2} Y={3} DistanceFromXY={4} Distance={5}",
id, pnt, pnt.X, pnt.Y, pnt.DistanceFromXY(1, 9), pnt.Distance());
}
rdr.Close();
Console.WriteLine("done");
}
static private string GetConnectionString()
{
// To avoid storing the connection string in your code,
// you can retrieve it from a configuration file.
return "Data Source=(local);Initial Catalog=AdventureWorks;"
+ "Integrated Security=SSPI";
}
}
バイト型としての UDT のバインド
場合によっては、UDT 列からそのままデータを取得する必要が生じることもあります。 たとえば、型がローカルに存在しない場合や、UDT のインスタンスを作成したくない場合などです。 SqlDataReader の GetBytes メソッドを使用して、生バイトをバイト配列に読み取ることができます。 このメソッドでは、バイトのストリームを、指定した列オフセットから、指定したバッファー オフセットから始まる配列のバッファーに読み取ることができます。 もう 1 つのオプションは、 GetSqlBytes または GetSqlBinary メソッドのいずれかを使用して、すべてのコンテンツを 1 回の操作で読み取る方法です。 どちらの場合も、UDT オブジェクトのインスタンスが作成されることはないので、クライアントのアセンブリで UDT への参照を設定する必要はありません。
例
この例では、SqlDataReader を使用して、Point データを生バイトとしてバイト配列に取得する方法を示します。 このコードでは、 System.Text.StringBuilder を使用して、生バイトをコンソール ウィンドウに表示される文字列形式に変換します。
Option Explicit On
Option Strict On
Imports System
Imports System.Data.Sql
Imports System.Data.SqlClient
Imports System.Data.SqlTypes
Imports System.Text
Module GetRawBytes
Sub Main()
Dim connectionString As String = GetConnectionString()
Using cnn As New SqlConnection(connectionString)
cnn.Open()
Dim cmd As New SqlCommand( _
"SELECT ID, Pnt FROM dbo.Points", cnn)
Dim rdr As SqlDataReader
rdr = cmd.ExecuteReader
While rdr.Read()
' Retrieve the value of the Primary Key column
Dim id As Int32 = rdr.GetInt32(0)
' Retrieve the raw bytes into a byte array
Dim buffer(31) As Byte
Dim byteCount As Integer = _
CInt(rdr.GetBytes(1, 0, buffer, 0, 31))
' Format and print bytes
Dim str As New StringBuilder
str.AppendFormat("ID={0} Point=", id)
Dim i As Integer
For i = 0 To (byteCount - 1)
str.AppendFormat("{0:x}", buffer(i))
Next
Console.WriteLine(str.ToString)
End While
rdr.Close()
Console.WriteLine("done")
End Using
End Sub
Private Function GetConnectionString() As String
' To avoid storing the connection string in your code,
' you can retrieve it from a configuration file.
Return "Data Source=(local);Initial Catalog=AdventureWorks;" _
& "Integrated Security=SSPI;"
End Function
End Module
using System;
using System.Data.Sql;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using System.Text;
class GetRawBytes
{
static void Main()
{
string connectionString = GetConnectionString();
using (SqlConnection cnn = new SqlConnection(connectionString))
{
cnn.Open();
SqlCommand cmd = new SqlCommand("SELECT ID, Pnt FROM dbo.Points", cnn);
SqlDataReader rdr = cmd.ExecuteReader();
while (rdr.Read())
{
// Retrieve the value of the Primary Key column
int id = rdr.GetInt32(0);
// Retrieve the raw bytes into a byte array
byte[] buffer = new byte[32];
long byteCount = rdr.GetBytes(1, 0, buffer, 0, 32);
// Format and print bytes
StringBuilder str = new StringBuilder();
str.AppendFormat("ID={0} Point=", id);
for (int i = 0; i < byteCount; i++)
str.AppendFormat("{0:x}", buffer[i]);
Console.WriteLine(str.ToString());
}
rdr.Close();
Console.WriteLine("done");
}
static private string GetConnectionString()
{
// To avoid storing the connection string in your code,
// you can retrieve it from a configuration file.
return "Data Source=(local);Initial Catalog=AdventureWorks;"
+ "Integrated Security=SSPI";
}
}
}
GetSqlBytes メソッドの使用例
この例では、GetSqlBytes メソッドを使用して、Point データを 1 回の操作で生バイトとして取得する方法を示します。 このコードでは、 StringBuilder を使用して、コンソール ウィンドウに表示される文字列形式に生バイトを変換します。
Option Explicit On
Option Strict On
Imports System
Imports System.Data.Sql
Imports System.Data.SqlClient
Imports System.Data.SqlTypes
Imports System.Text
Module GetRawBytes
Sub Main()
Dim connectionString As String = GetConnectionString()
Using cnn As New SqlConnection(connectionString)
cnn.Open()
Dim cmd As New SqlCommand( _
"SELECT ID, Pnt FROM dbo.Points", cnn)
Dim rdr As SqlDataReader
rdr = cmd.ExecuteReader
While rdr.Read()
' Retrieve the value of the Primary Key column
Dim id As Int32 = rdr.GetInt32(0)
' Use SqlBytes to retrieve raw bytes
Dim sb As SqlBytes = rdr.GetSqlBytes(1)
Dim byteCount As Long = sb.Length
' Format and print bytes
Dim str As New StringBuilder
str.AppendFormat("ID={0} Point=", id)
Dim i As Integer
For i = 0 To (byteCount - 1)
str.AppendFormat("{0:x}", sb(i))
Next
Console.WriteLine(str.ToString)
End While
rdr.Close()
Console.WriteLine("done")
End Using
End Sub
Private Function GetConnectionString() As String
' To avoid storing the connection string in your code,
' you can retrieve it from a configuration file.
Return "Data Source=(local);Initial Catalog=AdventureWorks;" _
& "Integrated Security=SSPI;"
End Function
End Module
using System;
using System.Data.Sql;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using System.Text;
class GetRawBytes
{
static void Main()
{
string connectionString = GetConnectionString();
using (SqlConnection cnn = new SqlConnection(connectionString))
{
cnn.Open();
SqlCommand cmd = new SqlCommand(
"SELECT ID, Pnt FROM dbo.Points", cnn);
SqlDataReader rdr = cmd.ExecuteReader();
while (rdr.Read())
{
// Retrieve the value of the Primary Key column
int id = rdr.GetInt32(0);
// Use SqlBytes to retrieve raw bytes
SqlBytes sb = rdr.GetSqlBytes(1);
long byteCount = sb.Length;
// Format and print bytes
StringBuilder str = new StringBuilder();
str.AppendFormat("ID={0} Point=", id);
for (int i = 0; i < byteCount; i++)
str.AppendFormat("{0:x}", sb[i]);
Console.WriteLine(str.ToString());
}
rdr.Close();
Console.WriteLine("done");
}
static private string GetConnectionString()
{
// To avoid storing the connection string in your code,
// you can retrieve it from a configuration file.
return "Data Source=(local);Initial Catalog=AdventureWorks;"
+ "Integrated Security=SSPI";
}
}
}
UDT パラメーターを使用した作業
ADO.NET コードでは、UDT は入力パラメーターと出力パラメーターのどちらとしても使用することができます。
クエリ パラメーターでの UDT の使用
UDT は、System.Data.SqlClient.SqlCommand オブジェクトの SqlParameter を設定するときにパラメーター値として使用できます。 SqlParameter オブジェクトの SqlDbType.Udt 列挙体は、Add メソッドを Parameters コレクションに呼び出すときに、パラメーターが UDT であることを示すために使用されます。 SqlCommand オブジェクトの UdtTypeName プロパティは、database.schema_name.object_name 構文を使用して、データベース内の UDT の完全修飾名を指定するために使用されます。 必須ではありませんが、完全修飾名を使用すると、コードを明確にすることができます。
Note
クライアント プロジェクトが、UDT アセンブリのローカル コピーを使用できることが前提です。
例
この例のコードでは、テーブルの UDT 列にデータを挿入するために、 SqlCommand オブジェクトと SqlParameter オブジェクトを作成します。 このコードでは、SqlDbType.Udt 列挙型を使用してデータ型を指定し、SqlParameter オブジェクトの UdtTypeName プロパティを使用して、データベース内の UDT の完全修飾名を指定します。
Option Explicit On
Option Strict On
Imports System
Imports system.Data
Imports System.Data.Sql
Imports System.Data.SqlClient
Module Module1
Sub Main()
Dim ConnectionString As String = GetConnectionString()
Dim cnn As New SqlConnection(ConnectionString)
Using cnn
Dim cmd As SqlCommand = cnn.CreateCommand()
cmd.CommandText = "INSERT INTO dbo.Points (Pnt) VALUES (@Point)"
cmd.CommandType = CommandType.Text
Dim param As New SqlParameter("@Point", SqlDbType.Udt)
param.UdtTypeName = "TestPoint.dbo.Point"
param.Direction = ParameterDirection.Input
param.Value = New Point(5, 6)
cmd.Parameters.Add(param)
cnn.Open()
cmd.ExecuteNonQuery()
Console.WriteLine("done")
End Using
End Sub
Private Function GetConnectionString() As String
' To avoid storing the connection string in your code,
' you can retrieve it from a configuration file.
Return "Data Source=(local);Initial Catalog=AdventureWorks;" _
& "Integrated Security=SSPI;"
End Function
End Module
using System;
using System.Data;
using System.Data.Sql;
using System.Data.SqlClient;
class Class1
{
static void Main()
{
string ConnectionString = GetConnectionString();
using (SqlConnection cnn = new SqlConnection(ConnectionString))
{
SqlCommand cmd = cnn.CreateCommand();
cmd.CommandText =
"INSERT INTO dbo.Points (Pnt) VALUES (@Point)";
cmd.CommandType = CommandType.Text;
SqlParameter param = new SqlParameter("@Point", SqlDbType.Udt); param.UdtTypeName = "TestPoint.dbo.Point"; param.Direction = ParameterDirection.Input; param.Value = new Point(5, 6); cmd.Parameters.Add(param);
cnn.Open();
cmd.ExecuteNonQuery();
Console.WriteLine("done");
}
static private string GetConnectionString()
{
// To avoid storing the connection string in your code,
// you can retrieve it from a configuration file.
return "Data Source=(local);Initial Catalog=AdventureWorks;"
+ "Integrated Security=SSPI";
}
}
}