web-dev-qa-db-ja.com

C#を使用して挿入された行のIDを取得する

列にAUTO_INCREMENTを使用して入力されるIDと呼ばれるフィールドを持つテーブルに行を挿入するクエリがあります。機能の次のビットのためにこの値を取得する必要がありますが、以下を実行すると、実際の値が0ではない場合でも常に0を返します。

MySqlCommand comm = connect.CreateCommand();
comm.CommandText = insertInvoice;
comm.CommandText += "\'" + invoiceDate.ToString("yyyy:MM:dd hh:mm:ss") + "\', " + bookFee + ", " + adminFee + ", " + totalFee + ", " + customerID +  ")";
int id = Convert.ToInt32(comm.ExecuteScalar());

私の理解によると、これはID列を返すはずですが、毎回0を返すだけです。何か案は?

編集:

私が走ると:

"INSERT INTO INVOICE (INVOICE_DATE, BOOK_FEE, ADMIN_FEE, TOTAL_FEE, CUSTOMER_ID) VALUES ('2009:01:01 10:21:12', 50, 7, 57, 2134);last_insert_id();"

私は得ます:

{"You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'last_insert_id()' at line 1"}
24
Elie

[編集:last_insert_id()への参照の前に「select」を追加しました]

挿入後に「select last_insert_id();」を実行するのはどうですか?

MySqlCommand comm = connect.CreateCommand();
comm.CommandText = insertInvoice;
comm.CommandText += "\'" + invoiceDate.ToString("yyyy:MM:dd hh:mm:ss") + "\', "  
    + bookFee + ", " + adminFee + ", " + totalFee + ", " + customerID +  ");";
    + "select last_insert_id();"

int id = Convert.ToInt32(comm.ExecuteScalar());

編集:duffymoが述べたように、パラメーター化されたクエリ (like this )を使用すると、実際にうまく機能します。


編集:パラメータ化されたバージョンに切り替えるまで、文字列で平和を見つけることができます。形式:

comm.CommandText = string.Format("{0} '{1}', {2}, {3}, {4}, {5}); select last_insert_id();",
  insertInvoice, invoiceDate.ToString(...), bookFee, adminFee, totalFee, customerID);
21
Michael Haren
MySqlCommand comm = connect.CreateCommand();
comm.CommandText = insertStatement;  // Set the insert statement
comm.ExecuteNonQuery();              // Execute the command
long id = comm.LastInsertedId;       // Get the ID of the inserted item
39
petra

LastInsertedIdを使用します。

ここに例を挙げて私の提案をご覧ください: http://livshitz.wordpress.com/2011/10/28/returning-last-inserted-id-in-c-using-mysql-db-provider/

3
Eli Livshitz

誰かが日付を受け取り、それを文字列としてデータベースに保存するのを見るのは面倒です。列タイプに現実を反映させてみませんか?

また、文字列連結を使用してSQLクエリが作成されているのにも驚いています。私はJava開発者であり、C#をまったく知りませんが、Java.sql.PreparedStatementの行にバインドメカニズムがどこかにあるのではないかと思いますSQLインジェクション攻撃から保護するために推奨されます。SQLの解析、検証、キャッシュが一度行われ、再利用できるため、パフォーマンスが向上する可能性もあります。

0
duffymo

実際には、ExecuteScalarメソッドは、返されるDataSetの最初の行の最初の列を返します。あなたの場合、あなたは挿入をしているだけで、実際にはデータをクエリしていません。挿入後にscope_identity()をクエリする必要があります(これはSQL Serverの構文です)と、答えが得られます。こちらをご覧ください:

リンケージ

EDIT:Michael Harenが指摘したように、MySqlを使用しているタグで言及したように、last_insert_id();を使用します。 scope_identity();の代わりに

0
BFree