2009-01-02 22 views
18

kullanarak alın. Sütuna bir AUTO_INCREMENT kullanarak doldurulmuş bir alan içeren bir tabloya satır eklemek için bir sorgum var. Ben işlevsellik sonraki parça için bu değeri elde etmek gerekiyor ama aşağıdaki çalıştırdığınızda, her zaman gerçek değeri 0 olmadığı halde 0 döndürür: benim anlayışıma göreGirilen satırın kimliğini C#

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

, bu kimliği dönmelidir sütun, ancak her seferinde 0 döndürür. Herhangi bir fikir?

DÜZENLEME:

Ben çalıştırdığınızda:

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

alıyorum:

{"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"} 
+0

1. Eğer işletilirse nihai CommandText gönderebilir miyim? 2.Kayıtlar gerçekten ekleniyor mu? –

+0

Sorgu gönderdim, hata ve evet, satırlar ekleniyor. – Elie

+0

Tamam, nasıl "SELECT last_insert_id();" sonunda? –

cevap

15

[Düzenleme: eklenen referanslar last_insert_id önce) ("select"]

Yolculuğunuzdan sonra "select last_insert_id();" yayınlamaya ne dersiniz? t?

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


Düzenleme: duffymo sözü gibi, gerçekten de parametreli sorguları like this kullanılarak hizmet verilebilir.


Düzenleme: Bir parametreli sürümüne geçiş kadar, String.format ile barış bulabilirsiniz:

comm.CommandText = string.Format("{0} '{1}', {2}, {3}, {4}, {5}); select last_insert_id();", 
    insertInvoice, invoiceDate.ToString(...), bookFee, adminFee, totalFee, customerID); 
+0

Sorguyu onsuz denedim. Kayıtlar gerçekten ekleniyor mu? –

+0

evet, kayıtlar ekleniyor. – Elie

+0

Tamam, nasıl "SELECT last_insert_id();" sonunda? –

0

Herhangi birinin bir Tarih alıp bir de saklayarak görmek beni rahatsız bir dize olarak veritabanı. Neden sütun türü gerçekliği yansıtmıyor?

Ayrıca dize birleştirme kullanılarak oluşturulmuş bir SQL sorgusu görmekten de şaşırdım. Ben bir Java geliştiricisiyim ve C# yi bilmiyorum, ama kütüphanede bir yerde java.sql.PreparedStatement satırlarında bağlama mekanizması olup olmadığını merak eder miydim? SQL enjeksiyon saldırılarına karşı koruma için önerilir. Diğer bir fayda da olası performans faydalarıdır çünkü SQL ayrıştırılabilir, doğrulanabilir, bir kez önbelleğe alınabilir ve yeniden kullanılabilir.

+0

OP, DB'de bir tarih sütunu kullanıyor olabilir. o kısmı göremiyoruz. Yine de, parametreli sorgular kullanmanız gerektiğini kabul ediyorum. Neyse ki herhangi bir metin ekleyerek bu kadar sıkı konuştuğunuz gibi görünmüyor (muhtemelen daha iyi olabilir). –

+0

sütun aslında bir tarihtir, ancak tarih nesnesini doğrudan eklemeye çalışırsam, tarihi 0s kümesine sıfırlatarak sorunlarım vardı. C# 'de yeniyim, ama sana katılıyorum, muhtemelen C# için PreparedStatement bir versiyonu ve bunu değiştireceğim. – Elie

+0

Sütun gerçekten bir tarihse, kodda biçimlendirme kalıbı olan "toString" çağrısı nedir? – duffymo

0

Aslında, ExecuteScalar yöntemi, döndürülen DataSet'in ilk satırının ilk sütununu döndürür. Durumunuzda, yalnızca bir Ekleme yapıyorsunuz, aslında herhangi bir veriyi sorgulamıyorsunuz. Ekledikten sonra scope_identity() 'yi sorgulamanız gerekir (SQL Server'ın sözdizimi) ve sonra cevabınızı alacaksınız. Buraya bakın:

Linkage

DÜZENLEME: Michael Haren işaret gibi, sen MySql,) (last_insert_id kullanmak kullandığınız Etiketinizdeki sözü; scope_identity() yerine;

+0

Cevabım, etiketlere göre Mysql için scope_identity sürümünü içerir. –

+0

Oh, benim hatam, MySql etiketini fark etmedim. Mesajımı düzenlerim. – BFree

+0

Sorun değil - sık sık onları özlüyorum. –

32
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 
+4

* LastInsertedId iş parçacığı güvenli değil. * Başka bir iş parçacığı bir şeyler ekliyorsa, LastInsertedId son eklenen kimliği db bağlantısıyla döndürür. Yani eğer birkaç iş parçacığı bunu yaparsa (veya aynı kullanıcıyla db'ye ayrı işlemleri bile), hatalı olacaktır. – Ted

+0

Awesome .. MysqlData'nın bunu sağladığını bile düşünmedim. harika. – Sami

+1

Bu cmd.LastInsertedId iş parçacığı güvenli değil ..... olabilir ama ben SELECT LAST_INSERT_ID() ile yapmak zorunda olduğunuz gibi aynı sorguya aynı bir ExecuteNonQuery çağrısı alındığını varsayalım. Başka bir evreden gelen başka bir aramanın, eklenen satırın ve kimliğin alınmasına "ara vermek" için gerçekten mümkün mü? Sanırım sunucu bu görevi yapıyor ve bu yüzden hemen yapıyor. LAST_INSERT_ID iş parçacığı güvenli mi? – MrCalvin

İlgili konular