次の方法で共有


ADO.NET でユーザー定義型 (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 を含むアセンブリが呼び出し元のアプリケーションで見つからない理由を特定します。 詳細については、「マネージド デバッグ アシスタントを使用したエラーの診断 」を参照してください。

SqlDataReader を使用して UDT にアクセスする

クライアント コードから System.Data.SqlClient.SqlDataReader を使用して、オブジェクトのインスタンスとして公開される UDT 列を含む結果セットを取得できます。

この例では、Main メソッドを使用して新しい SqlDataReader オブジェクトを作成する方法を示します。 このコード例では、次の操作が行われます。

  1. Main メソッドは、新しい SqlDataReader オブジェクトを作成し、Point という名前の UDT 列を持つ Points テーブルから値を取得します。

  2. Point UDT は、整数として定義された X 座標と Y 座標を公開します。

  3. UDT は、Distance メソッドと GetDistanceFromXY メソッドを定義します。

  4. このサンプル コードでは、UDT の機能を例示するために主キーと UDT 列の値を取得します。

  5. このサンプル コードは、Point.Distance メソッドと Point.GetDistanceFromXY メソッドを呼び出します。

  6. 結果はコンソール ウィンドウに表示されます。

Note

アプリケーションでは、事前に UDT アセンブリへの参照が設定されている必要があります。

  • C# を する
  • Visual Basic .NET の
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=AdventureWorks2022"
                       + "Integrated Security=SSPI";
            }
        }
    }
}

UDT をバイトとしてバインドする

状況によっては、UDT 列から生データを取得することが必要になる場合があります。 型がローカルで使用できない場合や、UDT のインスタンスをインスタンス化したくない場合があります。 SqlDataReaderGetBytes メソッドを使用して、生バイトをバイト配列に読み込むことができます。 このメソッドでは、バイトのストリームを、指定した列オフセットから、指定したバッファー オフセットから始まる配列のバッファーに読み取ることができます。 もう 1 つのオプションは、GetSqlBytes メソッドまたは GetSqlBinary メソッドのいずれかを使用し、1 回の操作ですべての内容を読み取る方法です。 どちらの場合も、UDT オブジェクトはインスタンス化されないため、クライアント アセンブリで UDT への参照を設定する必要はありません。

この例では、SqlDataReaderを使用して、Point データを生バイトとしてバイト配列に取得する方法を示します。 このコードでは、System.Text.StringBuilder を使用して、生バイトをコンソール ウィンドウに表示される文字列形式に変換します。

  • C# を する
  • Visual Basic .NET の
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=AdventureWorks2022"
            + "Integrated Security=SSPI";
    }
  }
}

GetSqlBytes の使用例

この例では、GetSqlBytes メソッドを使用して、Point データを 1 回の操作で生バイトとして取得する方法を示します。 このコードでは、StringBuilder を使用して、生バイトをコンソール ウィンドウに表示される文字列形式に変換します。

  • C# を する
  • Visual Basic .NET の
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=AdventureWorks2022"
            + "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 の完全修飾名を指定するために使用されます。 コードのあいまいさを回避するには、完全修飾名を使用する必要があります。

クライアント プロジェクトが、UDT アセンブリのローカル コピーを使用できることが前提です。

この例のコードでは、テーブル内の UDT 列にデータを挿入する SqlCommand オブジェクトと SqlParameter オブジェクトを作成します。 このコードでは、SqlDbType.Udt 列挙型を使用してデータ型を指定し、SqlParameter オブジェクトの UdtTypeName プロパティを使用して、データベース内の UDT の完全修飾名を指定します。

  • C# を する
  • Visual Basic .NET の
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=AdventureWorks2022"
            + "Integrated Security=SSPI";
    }
  }
}
  • ADO.NET のユーザー定義型にアクセスする