質問

IDというフィールドを持つテーブルに行を挿入するクエリがあります。このフィールドには、列のAUTO_INCREMENTを使用してデータが入力されます。次の機能のためにこの値を取得する必要がありますが、次を実行すると、実際の値が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"}
役に立ちましたか?

解決

[編集:" select"を追加last_insert_id()への参照前]

" 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);

他のヒント

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

LastInsertedIdを使用します。

ここで例を挙げて私の提案を見る: http://livshitz.wordpress.com/2011/10/28/returning-last-inserted-id-in-c-using-mysql-db-provider/

日付を取得してデータベースに文字列として保存する人を見るのは面倒です。列のタイプに現実を反映させないのはなぜですか?

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

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

リンク

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

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top