@@IDENTITY 関数 vs SCOPE_IDENTITY() 関数 vs IDENT_CURRENT() 関数: ID 値を取得する最適な方法は?
SQL Server 2005 では、INSERT
ステートメントの OUTPUT
句を使用して、自動生成された ID 値を含む挿入された行の情報を取り出すことができます。これは、@@IDENTITY
関数や SCOPE_IDENTITY()
関数を使用するよりも効率的で信頼性の高い方法です。
方法
以下の手順で、OUTPUT
句を使用して ID 値を取得できます。
INSERT
ステートメントを作成します。OUTPUT
句を追加します。OUTPUT
句によって返される結果セットから ID 値を取得します。
例
以下の例では、Customers
テーブルに新しい顧客を挿入し、OUTPUT
句を使用して自動生成された ID 値を取得します。
INSERT INTO Customers (FirstName, LastName)
OUTPUT INSERTED.CustomerID
VALUES ('John', 'Doe');
この例では、OUTPUT
句によって返される結果セットには、1 つの列 (CustomerID
) が含まれます。この列には、挿入された行の ID 値が含まれます。
ID 値の取得
OUTPUT
句によって返される結果セットは、SELECT
ステートメントの結果セットと同様に処理できます。ID 値を取得するには、以下の方法を使用できます。
- LINQ
var context = new MyContext();
var customer = new Customer
{
FirstName = "John",
LastName = "Doe"
};
context.Customers.Add(customer);
context.SaveChanges();
var customerId = customer.CustomerID;
- ADO.NET
using (var connection = new SqlConnection("..."))
{
using (var command = new SqlCommand("INSERT INTO Customers (FirstName, LastName) OUTPUT INSERTED.CustomerID VALUES (@FirstName, @LastName)", connection))
{
command.Parameters.AddWithValue("@FirstName", "John");
command.Parameters.AddWithValue("@LastName", "Doe");
connection.Open();
var customerId = (int)command.ExecuteScalar();
}
}
利点
OUTPUT
句を使用する方法は、@@IDENTITY
関数や SCOPE_IDENTITY()
関数を使用するよりもいくつかの利点があります。
- 効率性
OUTPUT
句は、@@IDENTITY
関数や SCOPE_IDENTITY()
関数よりも効率的です。これは、OUTPUT
句は 1 つのクエリで ID 値を取得できるためです。一方、@@IDENTITY
関数や SCOPE_IDENTITY()
関数は、2 つのクエリが必要です。
- 信頼性
OUTPUT
句は、SQL Server 2005 の INSERT
ステートメントで自動生成された ID 値を取得するための効率的で信頼性の高い方法です。
C#
using System;
using System.Data.SqlClient;
namespace OutputClauseExample
{
class Program
{
static void Main(string[] args)
{
// 接続文字列
const string connectionString = "Data Source=localhost;Initial Catalog=Test;Integrated Security=True";
// INSERT ステートメント
const string sql = @"
INSERT INTO Customers (FirstName, LastName)
OUTPUT INSERTED.CustomerID
VALUES (@FirstName, @LastName)";
// パラメータ
var parameters = new SqlParameter[]
{
new SqlParameter("@FirstName", "John"),
new SqlParameter("@LastName", "Doe")
};
// SqlConnection オブジェクトを作成
using (var connection = new SqlConnection(connectionString))
{
// SqlCommand オブジェクトを作成
using (var command = new SqlCommand(sql, connection))
{
// パラメータを追加
command.Parameters.AddRange(parameters);
// コマンドを開く
connection.Open();
// INSERT ステートメントを実行
var customerId = (int)command.ExecuteScalar();
// 結果を出力
Console.WriteLine("CustomerID: {0}", customerId);
}
}
}
}
}
SQL
INSERT INTO Customers (FirstName, LastName)
OUTPUT INSERTED.CustomerID
VALUES ('John', 'Doe');
実行結果
CustomerID: 1
説明
- 最初に、
SqlConnection
オブジェクトを作成して、データベースへの接続を開きます。 - 次に、
SqlCommand
オブジェクトを作成して、INSERT
ステートメントを指定します。 INSERT
ステートメントのパラメータとして、FirstName
とLastName
の値を指定します。SqlCommand
オブジェクトのExecuteScalar()
メソッドを使用して、INSERT
ステートメントを実行します。ExecuteScalar()
メソッドによって返される値は、挿入された行の ID 値です。- 最後に、ID 値を出力します。
補足
このサンプルコードは、基本的な例です。実際には、さまざまな方法で OUTPUT
句を使用できます。詳細については、以下のリソースを参照してください。
ID 値を取得するその他の方法
@@IDENTITY
関数は、最後に挿入された行の ID 値を取得するために使用できます。
INSERT INTO Customers (FirstName, LastName)
VALUES ('John', 'Doe');
SELECT @@IDENTITY;
BEGIN TRAN
INSERT INTO Customers (FirstName, LastName)
VALUES ('John', 'Doe');
SELECT SCOPE_IDENTITY();
COMMIT TRAN
IDENT_CURRENT('table_name')
関数は、指定されたテーブルの最後に挿入された行の ID 値を取得するために使用できます。
INSERT INTO Customers (FirstName, LastName)
VALUES ('John', 'Doe');
SELECT IDENT_CURRENT('Customers');
これらの方法の比較
方法 | 利点 | 欠点 |
---|---|---|
OUTPUT 句 | 効率的 | 並列実行プランでは誤った値を返す可能性がある |
@@IDENTITY 関数 | シンプル | 並列実行プランでは誤った値を返す可能性がある |
SCOPE_IDENTITY() 関数 | 信頼性が高い | トランザクション内で使用する必要がある |
IDENT_CURRENT('table_name') | 汎用性が高い | トランザクション内で使用する必要がない |
OUTPUT
句は、SQL Server 2005 で自動生成された ID 値を取得するための効率的で信頼性の高い方法です。ただし、並列実行プランを使用している場合は、誤った値を返す可能性があります。他の方法は、それぞれ異なる利点と欠点があります。要件に応じて、適切な方法を選択する必要があります。
sql sql-server-2005 insert