Microsoft.Data.SqlClient ile parametreleri yapılandırın.

Parametreler, değerleri bir komuta kendi Transact-SQL (T-SQL) metninden ayrı olarak gönderir. SQL ifadelerine değerleri birleştirmek veya interpolasyon yapmak yerine SqlParameter nesnelerini kullanın. Parametreler, SQL enjeksiyonuna karşı korumaya yardımcı olur ve değerin veritabanı türünü korur.

Bu makaledeki örnekler, connection adlı açık bir SqlConnection öğesinin AdventureWorks örnek veritabanını hedeflediğini varsayar.

C# örnekleri için using Microsoft.Data.SqlClient; gerekir. SqlDbType kullanan örnekler ayrıca using System.Data; gerektirir.

Giriş parametreleri ekleyin

Komut metnine her değer yer tutucu için bir parametre ekleyin. Parametrenin SQL Server tipini belirtin ve değerini atayın:

const string sql = """
    SELECT ProductID, Name, ListPrice
    FROM Production.Product
    WHERE ProductSubcategoryID = @subcategoryId
      AND ListPrice >= @minimumPrice
    ORDER BY ListPrice;
    """;

using var command = new SqlCommand(sql, connection);
command.Parameters.Add("@subcategoryId", SqlDbType.Int).Value = 2;
command.Parameters.Add("@minimumPrice", SqlDbType.Money).Value = 1_000m;

using SqlDataReader reader = command.ExecuteReader();
while (reader.Read())
{
    Console.WriteLine(
        $"{reader.GetInt32(0)}: {reader.GetString(1)} ({reader.GetDecimal(2):C})");
}

Komut metninde ve SqlParameter içinde parametre adı için aynı büyük/küçük harf kullanımını kullanın. SQL Server, değişken adlarını sunucu harmanlamasını kullanarak eşleştirir; bu nedenle bir uyumsuzluk, büyük/küçük harfe duyarlı bir harmanlamaya sahip sunucuda "Skaler değişken bildirilmelidir" hatasına neden olur.

Parametre yer tutucularıyla çalışma

Microsoft. Data.SqlClient, adlandırılmış parametreleri şu biçimde @parameterNamekullanır. Pozisyonsal soru işareti (?) yer tutucuları desteklenmiyor.

Parametre yer tutucuları değerleri temsil eder, SQL tanımlayıcıları veya sözdizimi değil. Bir tablo adı, sütun adı, sıralama yönü veya tüm SQL parçası için parametre kullanamazsınız. Bir uygulama bir tanımlayıcıyı dinamik olarak seçerse, onu izin listesine göre doğrulayın ve doğrulamadan sonra komut metnine ekleyin. Tüm veri değerlerini parametre olarak aktarmaya devam edin.

Metin komutları için, Microsoft.Data.SqlClient parametreli ifadeleri SQL Server'a sp_executesql aracılığıyla gönderir. SQL Server, ifade metni ve parametre tanımları aynı kaldığında bir yürütme planını yeniden kullanabilir.

Parametre veri türlerini belirtme

Uygulamanın hedef SQL Server tipini bildiği zaman SqlDbType açıkça ayarlayın. Ayrıca, uygun olduğunda Size, Precision ve Scale gibi türe özgü meta verileri ayarlayın.

Bu örnek, Person.Person içindeki nvarchar(50) ve datetime sütunlarıyla eşleşir:

const string sql = """
    SELECT BusinessEntityID, FirstName, LastName
    FROM Person.Person
    WHERE LastName = @lastName
      AND ModifiedDate >= @modifiedSince
    ORDER BY BusinessEntityID;
    """;

using var command = new SqlCommand(sql, connection);

SqlParameter lastName = command.Parameters.Add(
    "@lastName",
    SqlDbType.NVarChar,
    50);
lastName.Value = "O'Brien";

SqlParameter modifiedSince = command.Parameters.Add(
    "@modifiedSince",
    SqlDbType.DateTime);
modifiedSince.Value = new DateTime(2013, 1, 1);

Parametre meta verilerinin hedef sütunla eşleştirilmesi, örtük dönüşümleri önler ve dize uzunluğu veya ondalık ölçekteki değişikliklerin parametre tanımını değiştirmesini engeller.

Ondalık değerler için hassasiyeti belirleyin ve ölçeği açıkça belirtin. Production.Product içindeki Weight sütunu decimal(8, 2) kullanır:

const string sql = """
    SELECT ProductID, Name, Weight
    FROM Production.Product
    WHERE Weight >= @minimumWeight
    ORDER BY Weight;
    """;

using var command = new SqlCommand(sql, connection);
SqlParameter minimumWeight = command.Parameters.Add(
    "@minimumWeight",
    SqlDbType.Decimal);
minimumWeight.Precision = 8;
minimumWeight.Scale = 2;
minimumWeight.Value = 10.25m;

NULL veritabanı değerlerini geçir

Bir veritabanı Value göndermek için NULL atayın. C#null, sıradan skaler parametreler için bir SQL ServerNULL'ı temsil etmez:

const string sql = """
    SELECT SalesOrderID, OrderDate, SalesPersonID
    FROM Sales.SalesOrderHeader
    WHERE (@salesPersonId IS NULL OR SalesPersonID = @salesPersonId)
    ORDER BY SalesOrderID;
    """;

using var command = new SqlCommand(sql, connection);
SqlParameter salesPersonId = command.Parameters.Add(
    "@salesPersonId",
    SqlDbType.Int);

int? selectedSalesPersonId = null;
salesPersonId.Value = selectedSalesPersonId.HasValue
    ? selectedSalesPersonId.Value
    : DBNull.Value;

Çıkarımsal metaveriyi seçici olarak kullanın

AddWithValue yöntemi, parametre meta verilerini çalışma zamanı değerinden türetir. Çıkarım, çıkarılan meta veriler kararlı ve veritabanı tipiyle eşleştiğinde kullanışlıdır. Dizi uzunlukları, ondalık hassasiyet veya diğer değer özellikleri değiştiğinde farklı parametre tanımları üretebilir.

Hedef şeması bilinen üretim komutları için, açık bir Add ile SqlDbType tercih edin. C# null öğesini AddWithValue öğesine geçirmeyin; bunun yerine türü belirtin ve DBNull.Value atayın.

Komut parametrelerini yeniden kullanın

Bir parametre oluşturun ve aynı komutu farklı değerlerle çalıştırdığınızda yalnızca Value değerini değiştirin:

const string sql = """
    SELECT TOP (1) Name, ListPrice
    FROM Production.Product
    WHERE ProductSubcategoryID = @subcategoryId
    ORDER BY ListPrice DESC;
    """;

using var command = new SqlCommand(sql, 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)}");
    }
}

Her çalıştırmada aynı isimle başka bir parametre eklemeyin. Mevcut parametreyi yeniden kullanın veya yeniden oluşturmadan önce koleksiyonu temizleyin.

Parametre yönünü ayarla

Direction özelliği, bir komutun parametreyi nasıl kullandığını tanımlar. Bunu bir ParameterDirection değere ayarlayın:

Yön Use
Input Bir değeri bir deyime veya saklı yordama gönderir. Bu değer varsayılandır.
Output Bir saklı yordam çıkış parametresinden bir değer alır.
InputOutput Başlangıç değeri gönderir ve güncellenmiş değeri alır.
ReturnValue T-SQL RETURN ifadesinden tam sayı değerini alır.

Çıkış, giriş/çıkış ve dönüş değeri parametreleri için, Value yalnızca komut bittikten sonra okuyun. Bir komut satır döndürürse, bu değerleri okumadan önce SqlDataReader öğesini kapatın veya dispose edin.

Tüm depolanan yordam örnekleri için bkz. Depolanan yordamlarla verileri değiştirme.

Parametreleri saklı yordamla kullanın

StoredProcedure ayarını belirleyin ve prosedürün parametre adlarını kullanın. Bu örnek, AdventureWorks'e dahil edilen dbo.uspGetEmployeeManagers yordamını çağırır:

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

Parametre adı, saklı yordam tarafından bildirilen isimle eşleşmelidir.

Tablo değerli parametreleri yapılandırma

Tablo değerli parametre, bir saklı yordama veya parametrizlenmiş ifadeye birden fazla satır gönderir. Yapılandırmak için:

  1. SqlDbType.Structuredayarlayın.
  2. TypeName öğesini veritabanı kullanıcı tanımlı tablo tipine ayarlayın.
  3. Bir DataTable, DbDataReader veya IEnumerable<SqlDataRecord> satır kaynağı atayın.

Tanımlanmış sütunları olan ve hiç satırı olmayan bir DataTable, boş bir tablo gönderir. Boş bir IEnumerable<SqlDataRecord>, ArgumentException oluşturur; o giriş formu için sıfır satır göndermek üzere C# null değerini atayın. DBNull.Value öğesini tablo değerli bir parametreye atamayın.

Tür oluşturma, satır eşleme ve tam örnekler için bkz. tablo değerli parametreler.

Akış değerlerini yapılandırın

Büyük bir değeri kademeli olarak sağlamak için bir Stream, XmlReader veya Value’yi TextReader’e atayın. Sınırlı bellek aktarımı için, (max), xml veya json parametre türü kullanın. Microsoft.Data.SqlClient, karakter olmayan (max) ve ikili türler ile eski büyük nesne türleri için çalıştırmadan önce kaynağı tamponlar.

Parametre türü değerle eşleşmelidir:

Değer Uyumlu SqlDbType değerler
Stream Binary, VarBinary, ya da miras Image tipi
TextReader Char, NChar, NVarChar, VarChar, eski Text ve NText türleri, Xml, veya Json
XmlReader Char, NChar, NVarChar, VarChar, eski Text ve NText türleri, Xml, veya Json

Microsoft.Data.SqlClient, nesne türü, InvalidCastException veya bildirilen boyut uyumsuz olduğunda SqlTypeException, SqlDbType ya da ArgumentException atar. Tam yükleme ve indirme örnekleri için SqlClient akış desteğine bakınız.

Parametre bilgilerini türet

DeriveParametersSQL Server'da saklanan bir prosedürün parametre meta verisini sorgular ve komutun mevcut parametre koleksiyonunun yerine yenisini koyar:

using var command = new SqlCommand(
    "dbo.uspGetEmployeeManagers",
    connection);
command.CommandType = CommandType.StoredProcedure;

SqlCommandBuilder.DeriveParameters(command);
command.Parameters["@BusinessEntityID"].Value = 6;

DeriveParameters her çağrıldığında ekstra bir veritabanına gidiş-dönüş gerektirir. Geliştirme sırasında gerektiğinde meta veri türetin, ardından performansa duyarlı kod yollarında parametreleri açıkça tanımlayın.