26

列に 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"}
4

5 に答える 5

47
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
于 2013-02-06T11:07:33.140 に答える
23

[編集: 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 が述べたように、このようなパラメーター化されたクエリを使用すると、実際にうまく機能します。


編集:パラメータ化されたバージョンに切り替えるまで、string.Formatで平和を見つけるかもしれません:

comm.CommandText = string.Format("{0} '{1}', {2}, {3}, {4}, {5}); select last_insert_id();",
  insertInvoice, invoiceDate.ToString(...), bookFee, adminFee, totalFee, customerID);
于 2009-01-02T02:48:54.073 に答える
3

LastInsertedIdを使用します。

ここに例を挙げて私の提案を表示します:http://livshitz.wordpress.com/2011/10/28/returning-last-inserted-id-in-c-using-mysql-db-provider/

于 2011-10-28T11:38:29.947 に答える
0

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

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

于 2009-01-02T02:55:20.893 に答える
0

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

リンケージ

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

于 2009-01-02T03:11:29.600 に答える