Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Transact-SQL (T-SQL) ifadelerini veya depolanmış prosedürleri çalıştırmak için kullanılır SqlCommand . Bir komut açık SqlConnection gerektirir. Komutu kullandıktan sonra atın ve bağlantıyı tekrar kullanmadan önce herhangi bir reader nesnesini atın.
Bu makaledeki örnekler, connection adlı açık bir SqlConnection öğesinin AdventureWorks örnek veritabanını hedeflediğini varsaymaktadır.
C# örnekleri için using Microsoft.Data.SqlClient; gereklidir.
SqlDbType, CommandType veya CommandBehavior kullanan örnekler de using System.Data; gerektirir.
Bağlantı kurulumu, kimlik doğrulama ve şifreleme için bkz. Bağlantı dizileri ve Şifreleme ve sertifika doğrulaması.
Bir çalıştırma yöntemi seçin
Beklenen sonucu eşleştiren yöntemi seçin:
| Method | Şu durumlarda kullanın: | Sonuç |
|---|---|---|
| ExecuteNonQuery | Komut veriyi veya şemayı değiştirir. | Etkilenen satır sayısı.
-1 sayım mevcut olmadığında da, SET NOCOUNT ON sayımları bastırdığında da meydana gelebilir. |
| ExecuteScalar | Tek bir değere ihtiyacınız var. | İlk satırın ilk sütunudur ya da sonuçta satır yoksa null. Bir veritabanı NULL olarak Value döndürülür. |
| ExecuteReader | Satırlara, birden fazla sonuç setine veya şemaya ihtiyacınız var. | Bir SqlDataReader. |
| ExecuteXmlReader | Komut, XML'i ExecuteXmlReader tarafından gereken biçimde döndürür. |
Bir XmlReader. |
Her yöntemin görev tabanlı asenkron bir karşılığı vardır. Çağıranın beklemeyi durdurması gerektiğinde bir CancellationToken geçirin. İptal ve zaman aşımı davranışı için bkz. Asenkron programlama.
Bir metin komutunu çalıştırın
CommandType.Text varsayılan değerdir. İfadeyi CommandText içine yerleştirin ve değerleri parametreler aracılığıyla iletin:
const string sql = """
SELECT ProductID, Name, ListPrice
FROM Production.Product
WHERE ProductSubcategoryID = @subcategoryId
ORDER BY ListPrice DESC;
""";
using var command = new SqlCommand(sql, connection);
command.Parameters.Add("@subcategoryId", SqlDbType.Int).Value = 2;
using SqlDataReader reader = command.ExecuteReader();
while (reader.Read())
{
Console.WriteLine(
$"{reader.GetInt32(0)} | {reader.GetString(1)} | {reader.GetDecimal(2):C}");
}
Parametre türleri, boyutlar, null değerler ve yönler için Parametreleri Yapılandır bölümüne bakınız. Güvenilmeyen değerleri CommandText içine birleştirmeyin.
Saklı bir yordam çalıştır
CommandType.StoredProcedure ayarlayın ve şema nitelikli yordam adını kullanın:
using var command = new SqlCommand(
"dbo.uspGetEmployeeManagers",
connection);
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add(
"@BusinessEntityID",
SqlDbType.Int).Value = 6;
using SqlDataReader reader = command.ExecuteReader();
while (reader.Read())
{
Console.WriteLine(
$"{reader.GetString(2)} {reader.GetString(3)}");
}
Microsoft.Data.SqlClient, CommandType.StoredProcedure ve CommandType.Text destekler.
CommandType.TableDirect ayarı, ArgumentOutOfRangeException oluşturur.
Her yöntemin ne verdiğini kontrol edin
Bir değere ihtiyacınız olduğunda kullanın ExecuteScalar :
using var command = new SqlCommand(
"SELECT COUNT(*) FROM Production.Product WHERE SellEndDate IS NULL;",
connection);
int currentProductCount = (int)command.ExecuteScalar()!;
Console.WriteLine($"Current products: {currentProductCount}");
ExecuteScalar, sonuçta satır yoksa DBNull.Value ve ilk değer bir veritabanı null ise NULL döndürür.
Veri değiştiren ifadeler için ExecuteNonQuery kullanın. Bu örnek, AdventureWorks'un değişmemesi için değişikliği geri alıyor:
using SqlTransaction transaction = connection.BeginTransaction();
using var command = new SqlCommand("""
UPDATE Sales.SalesOrderHeader
SET Status = @status
WHERE SalesOrderID = @salesOrderId;
""", connection, transaction);
command.Parameters.Add("@status", SqlDbType.TinyInt).Value = 2;
command.Parameters.Add("@salesOrderId", SqlDbType.Int).Value = 43659;
int rowsAffected = command.ExecuteNonQuery();
Console.WriteLine($"Rows affected: {rowsAffected}");
transaction.Rollback();
SET NOCOUNT ON etkilenen satır sayılarını bastırır, böylece ExecuteNonQuery bir ifade veri değiştirdiğinde bile -1 geri döndürebilir.
Bir FOR XML sonuç için ExecuteXmlReader kullanın:
using var command = new SqlCommand("""
SELECT TOP (3) ProductID, Name
FROM Production.Product
ORDER BY ProductID
FOR XML PATH('Product'), ROOT('Products');
""", connection);
using System.Xml.XmlReader reader = command.ExecuteXmlReader();
reader.MoveToContent();
Console.WriteLine(reader.ReadOuterXml());
Yerel bir işlem kullanın
Bir bağlantının etkin bir yerel SqlTransaction varsa, bu işlemi bağlantıda yürütülen her komuta atayın. Bu örnek, yaptığı değişikliği geri alır; böylece AdventureWorks değişmeden kalır:
using SqlTransaction transaction = connection.BeginTransaction();
using var command = new SqlCommand("""
UPDATE Sales.SalesOrderHeader
SET Status = @status
WHERE SalesOrderID = @salesOrderId;
""", connection, transaction);
command.Parameters.Add("@status", SqlDbType.TinyInt).Value = 2;
command.Parameters.Add("@salesOrderId", SqlDbType.Int).Value = 43659;
command.ExecuteNonQuery();
transaction.Rollback();
Yalnızca uygulama işlemin tamamını kabul ettiğinde Rollback yerine Commit çağırın. Aktif işleme başvurmayan bir komut InvalidOperationException fırlatır. İşlem başka bir bağlantıya aittiyse de yürütme başarısız olur. İşlem sınırları ve geri alma için Yerel işlemlere bakınız.
Bir komut zaman aşımı ayarlayın
CommandTimeout komut yürütme ve kümülatif ağ okuma beklemelerini saniyelerle sınırlar. Bir komut, bir tanesi yapılandırılmışsa bağlantının Command Timeout ayarını kullanır. Aksi takdirde, varsayılan süre 30 saniyedir.
0 değerinin zaman sınırı yoktur. Negatif değerler ArgumentException fırlatır.
Zaman aşımı dolduğunda, komut Number değeri -2 olarak ayarlanmış SqlException hatasını fırlatır:
using var command = new SqlCommand(
"WAITFOR DELAY '00:00:05';",
connection)
{
CommandTimeout = 1
};
try
{
command.ExecuteNonQuery();
}
catch (SqlException exception) when (exception.Number == -2)
{
Console.WriteLine("The command timed out.");
}
Connect Timeout bağlantı kurulumu ve havuz beklemelerini sınırlar.
CommandTimeout komut yürütme başladıktan sonra başlar. Daha fazla bilgi için Bağlantı seçenekleri bölümüne bakınız.
Sınırlı bir zaman aşımını ve iptal tokenını birlikte kullanın. Zaman aşımı, veritabanı operasyonuna bir sınır koyar. Token'ın iptal edilmesi, zaman aşımı bitmeden kontrolü arayana geri verebilir. İptal ve zaman aşımının aynı istisna yarattığını varsaymayın.
Komutları yeniden kullanın ve hazırlayın
Bir parametreyi bir kez ekleyin ve her çalıştırma bittikten sonra değerini değiştirin:
using var command = new SqlCommand("""
SELECT TOP (1) Name, ListPrice
FROM Production.Product
WHERE ProductSubcategoryID = @subcategoryId
ORDER BY ListPrice DESC;
""", connection);
SqlParameter subcategoryId = command.Parameters.Add(
"@subcategoryId",
SqlDbType.Int);
foreach (int id in new[] { 1, 2, 3 })
{
subcategoryId.Value = id;
using SqlDataReader reader = command.ExecuteReader();
if (reader.Read())
{
Console.WriteLine($"{id}: {reader.GetString(0)}");
}
}
Prepare öğesini yalnızca ölçümler bunu gerektirdiğinde çağırın.
Prepare parametresiz saklı yordamları veya metin komutlarını hazırlamaz. Parametreleştirilmiş metin için, Prepare çağırmadan önce her parametreye Size, Precision ve Scale gibi tam meta veriler ayarlayın.
Sorun giderme komutları
Veritabanı işlemi etrafında SqlException öğesini yakalayın ve sunucu birden fazla hata döndürdüğünde Errors koleksiyonunu inceleyin. Komut hataları, uyarılar ve bilgilendirici mesajlar için bkz. Hataları ve mesajları ele almak.
Bir hata daha fazla bağlam gerektirdiğinde tanılama sayaçları, olay kaynağı izleme ve SqlClient sorun giderme rehberini kullanın. Yalnızca komut tekrarı güvenli olduğunda yapılandırılabilir yeniden deneme mantığını uygulayın.