2011-01-07 19 views
35

Buna ilgili soru var:SqlCommand Parametreleri eklerken "SqlDbType" ve "size" ne zaman kullanılmalıdır?

What's the best method to pass parameters to SQLCommand?

Ama farklar ve farklı şekillerde ile herhangi bir sorun varsa öğrenmek isteyen.

using (SqlConnection conn = new SqlConnection(connectionString)) 
using (SqlCommand cmd = new SqlCommand(SQL, conn)) 
{ 
    cmd.CommandType = CommandType.Text; 
    cmd.CommandTimeout = Settings.Default.reportTimeout; 
    cmd.Parameters.Add("type", SqlDbType.VarChar, 4).Value = type; 

    cmd.Connection.Open(); 

    using (SqlDataAdapter adapter = new SqlDataAdapter(cmd)) 
    { 
     adapter.Fill(ds); 
    } 
     //use data      
} 

Şimdi cmd parametreleri eklemek için çeşitli yollar vardır ve merak ediyorum en iyisidir:

cmd.Parameters.Add("@Name", SqlDbType.VarChar, 20).Value = "Bob"; 
cmd.Parameters.Add("@Name", SqlDbType.VarChar).Value = "Bob"; 
cmd.Parameters.Add("@Name").Value = "Bob"; 
cmd.Parameters.AddWithValue("@Name", "Bob"); 

uzunluğunu sahip

Genellikle böyle bir yapı şey kullanın Varchars geçerken alan, daha sonra veritabanında değiştirilebilecek bir sihirli değeri olduğu için tercih edilmez. Bu doğru mu? Bu şekilde bir varchar iletirken herhangi bir soruna neden olur mu (performans ya da diğer), varsayılanı varchar (max) ya da veritabanı eşdeğerine varsayılan olarak kabul ediyorum. Bu işe yarayacak kadar mutluyum.

Yukarıda listelediğim üçüncü veya dördüncü seçenekleri kullanmam durumunda SqlDbType enum'un kaybı beni daha fazla ilgilendiren bir bölümdür. Bu işe yaramayacak durumlar var varchar varchar ile yanlış ya da tersi ya da belki de ondalık ile ilgili sorunlar hakkında hayal edebiliyorum sorunları hayal edebiliyorum ....

Veritabanı açısından I Uzunluğundan daha fazla değişiklik olasılığı daha fazladır; Tecrübelerime göre

+3

Sorunuzu yanıtlamıyorken, 'SqlDataAdapter.Fill()' çağrılmadan önce bağlantıyı açmanız gerekmediğini ve bunu yapmamanın yararı olduğunu biliyorsunuzdur? –

+0

@Rowland iyi bir nokta. Bunu benim kodumda bir gözetim olmasına rağmen biliyordum. Orijinal kod bloğunu bir adaptör değil SqlDataReader kullandığım bir yerden aldım (Bu bağlantıyı açmanız gerekecek mi?). Yaramaz kopyala/yapıştır programlama için budur :-). Şimdi kodumda sabitlendi. – PeteT

+0

sadece şunu söyleyebilirim, çünkü bu "insanların bilmeyebileceği" belirsiz ipuçlarından biri " –

cevap

49

, ben bu şeyleri emin olacaktır:

  • o parametre için veri türünü tanımlayan siz olduğundan emin olun. ADO.NET tahmin de iyi bir iş yapar, ancak bazı durumlarda, bu korkunç kapalı olabilir - bu yüzden bu yöntemi önleyeceğini: ADO.NET Letting

    cmd.Parameters.Add("@Name").Value = "Bob"; 
    cmd.Parameters.AddWithValue("@Name", "Bob"); 
    

    olduğunu geçirilen değere göre parametrenin türünü tahmin zor ve herhangi bir nedenle kapalı ise, bu izlemek ve bulmak için gerçekten zor böcek! Bir DBNull.Value'u ilettiğinizde ne olacağını hayal edin - ADO.NET bunun için hangi veri tipini seçmelidir?

    Sadece açık olun - ne tür bir şey istiyorsunuz?

  • sen dize parametreleri kullanıyorsanız, açıkça uzunluğu tanımlamak emin olun - çok, bu yüzden bu yöntemi önleyeceğini:

    cmd.Parameters.Add("@Name", SqlDbType.VarChar).Value = "Bob"; 

    Eğer bir uzunluğa, ADO girmezseniz

    . NET, bazı rasgele değerlere veya bir değer olarak iletilen dizinin uzunluğuna veya başka bir şeye göre varsayılan olabilir. Ve eğer uzunluğunuz depolanan proc'un gerçekten beklediği ile uyuşmuyorsa, dönüşüm ve diğer hoş olmayan sürprizleri görebilirsiniz. Yani bir dizge tanımlarsanız, uzunluğunu da tanımlayın!senin durumunda Yani

, gerçekten benim için çalışan tek yaklaşım burada bu biridir:

cmd.Parameters.Add("@Name", SqlDbType.VarChar, 20).Value = "Bob"; 

bir) açıkça kullanmak için veri türünü tanımlar çünkü ve b) uzunluğunu belirler dize açıkça.

+0

Saklı yordamı kullanıyorsanız, parametre türünü yalnızca aşağıdaki meta veriden elde edemezsiniz. SqlCommandBuilder.DeriveParameters (cmd)? – devinbost

+0

Uzunluk, temel alınan parametre tanımınınki kadar mı geçti? Ve eğer öyleyse, bu tür bir DRY'yi ihlal etmiyor mu? – tbone

4

Türü eklediğinizde, isteklerin önbelleğe alınmış sorgu planını kullanarak performansı artırması daha olasıdır.

İşte MSDN'den bir alıntı: onlar veritabanı sunucusu doğru düzgün bir önbelleğe alınan sorgu planı ile gelen komutu eşleştirmeye yardımcı çünkü

Parametreli komutlar da, sorgu yürütme performansını artırabilir.

Execution Plan Caching and Reuse adresinde okumak için daha fazla bilgi.

+0

Tüm Pete'in seçenekleri paramterlenmiş, bu yüzden parametreleri farklı şekillerde eklemek performansı etkiliyorsa şaşırırdım - kesinlikle bağlı olduğunuz makalede açıkça belirtilmiyor. –

+4

Katılmıyorum. Tanımlayan makalede, parametrenin mümkün olduğunca kesin bir şekilde tanımlanması, daha sonra kullanılacak olan önbelleğe alınmış bir sorgu planının ve daha yüksek performansın olması daha olasıdır. Alt Parametre Basit Parametreleme şunu söylüyor: SQL Server'da Transact-SQL deyimlerindeki parametreler veya parametre işaretleyicileri kullanmak, ilişkisel motorun mevcut, önceden derlenmiş yürütme planları ile yeni SQL deyimlerini eşleştirmesini sağlar. – StefanE

İlgili konular