web-dev-qa-db-ja.com

C#SQL挿入コマンド

誰かがレコードを挿入する次の2つの方法でパフォーマンスが向上することを教えてもらえますか?

ケース1

SqlCommand cmd = new SqlCommand();

for (int i = 0; i < 10000; i++)
{
  cmd = new SqlCommand("insert into test(id, name) value('" + i + "', '" + i + "')");
  cmd.ExecuteNonQuery();
}

ケース2

string sql = null;

for (int i = 0; i < 10000; i++)
{
  sql += "insert into test(id, name) value('" + i + "', '" + i + "')";
}

SqlCommand cmd = new SqlCommand(sql, conn);
cmd.ExecuteNonQuery();
6
RoyT

まず最初に:[〜#〜] stop [〜#〜] SQLコードを連結します!!これはハッカーへの招待あらゆる場所でSQLインジェクションを使用して攻撃します!代わりにパラメータ化クエリを使用してください!

私はこのソリューションを使用します:パラメータ化されたクエリでsingle SqlCommandを作成し、それを実行します:

string stmt = "INSERT INTO dbo.Test(id, name) VALUES(@ID, @Name)";

SqlCommand cmd = new SqlCommand(smt, _connection);
cmd.Parameters.Add("@ID", SqlDbType.Int);
cmd.Parameters.Add("@Name", SqlDbType.VarChar, 100);

for (int i = 0; i < 10000; i++)
{
    cmd.Parameters["@ID"].Value = i;
    cmd.Parameters["@Name"].Value = i.ToString();

    cmd.ExecuteNonQuery();
}

または、SqlBulkCopyを使用します。特に10'000を超える行を挿入する場合は特にそうです。

62
marc_s

2番目のアプローチは、INSERTコマンドを一度に送信するため、1番目よりも高速に見えます。最初の例では、各ExecuteNonQueryについてSQLサーバーへの往復があります。

ただし、一括挿入コマンドを試してみてください: BULK INSERT(Transact-SQL) 、指定したどのオプションよりもパフォーマンスが向上すると思います。

[]の

6
Fabio

2つ目はうまくいきません。

ただし、SQL Server 2008には 1つのINSERTステートメントに複数の行を挿入する の構文があり、提案した両方のオプションよりも高速になると思います。

INSERT INTO test (id, name)
VALUES
('1', 'foo'),
('2', 'bar'),
('3', 'baz')
 -- etc...

ただし、本当に高いパフォーマンスが必要な場合は、 SqlBulkCopy クラスの使用を検討してください。

1
Mark Byers

現状では、どちらのケースも機能しないことに注意してください。

ケース#1では、接続を指定する必要があります。

ケース#2では、次のように複数のコマンドを実行するために、ステートメントをセミコロンで終了する必要があります。

string sql = null;

for (int i = 0; i < 10000; i++)
{
  sql += "insert into test(id, name) value('" + i + "', '" + i + "');";
}

SqlCommand cmd = new SqlCommand(sql, conn);
cmd.ExecuteNonQuery();

最終的には、数千行で自分でテストするのが最善の方法です。私の推測は、単一のSqlCommandオブジェクトのみを設定する必要があるだけでなく、データベースに1回しかヒットしないので、ケース2の方がパフォーマンスが優れているでしょう。

1
Kiley Naro

2番目の方法は、1回の往復で終わるため、おそらく高速です。 パラメータ化されたクエリ を使用しないため、どちらもひどいです。

0
dasblinkenlight