Mengonfigurasi parameter dan jenis data parameter
Objek perintah menggunakan parameter untuk meneruskan nilai ke SQL pernyataan atau prosedur yang disimpan, memberikan pemeriksaan dan validasi jenis. Tidak seperti teks perintah, input parameter diperlakukan sebagai nilai literal, bukan sebagai kode yang dapat dieksekusi. Ini membantu menjaga dari serangan "injeksi SQL", di mana penyerang memasukkan perintah yang membahayakan keamanan di server ke dalam pernyataan SQL.
Perintah parameter juga dapat meningkatkan kinerja eksekusi kueri, karena membantu server database secara akurat mencocokkan perintah masuk dengan rencana kueri cache yang tepat. Untuk informasi selengkapnya, lihat Penembolokan Rencana Eksekusi dan Penggunaan Kembali dan Parameter dan Penggunaan Kembali Rencana Eksekusi. Selain manfaat keamanan dan kinerja, perintah parameter memberikan metode yang nyaman untuk mengatur nilai yang diteruskan ke sumber data.
Objek DbParameter dapat dibuat dengan menggunakan konstruktornya, atau dengan menambahkannya ke DbParameterCollection dengan memanggil metode Add
dari koleksi DbParameterCollection. Metode Add
akan menggunakan argumen konstruktor atau objek parameter yang ada sebagai masukan, bergantung pada penyedia data.
Memasok properti ParameterDirection
Saat menambahkan parameter, Anda harus menyediakan properti ParameterDirection untuk parameter selain parameter input. Tabel berikut ini memperlihatkan nilai ParameterDirection
yang bisa Anda gunakan dengan enumerasi ParameterDirection.
Nama anggota | Deskripsi |
---|---|
Input | Parameter adalah parameter input. Ini adalah default. |
InputOutput | Parameter dapat melakukan input dan output. |
Output | Parameter adalah parameter output. |
ReturnValue | Parameter mewakili nilai pengembalian dari operasi seperti prosedur yang disimpan, fungsi bawaan, atau fungsi yang ditentukan pengguna. |
Bekerja dengan tempat penampung parameter
Sintaks untuk tempat penampung parameter bergantung pada sumber data. Penyedia data .NET Framework menangani penamaan dan menentukan parameter dan tempat penampung parameter secara berbeda. Sintaks ini disesuaikan ke sumber data tertentu, seperti yang dijelaskan dalam tabel berikut.
Penyedia data | Sintaks penamaan parameter |
---|---|
System.Data.SqlClient | Menggunakan parameter bernama dalam format @ parametername. |
System.Data.OleDb | Menggunakan penanda parameter posisi yang ditunjukkan oleh tanda tanya (? ). |
System.Data.Odbc | Menggunakan penanda parameter posisi yang ditunjukkan oleh tanda tanya (? ). |
System.Data.OracleClient | Menggunakan parameter bernama dalam format : parmname (atau parmname). |
Menentukan jenis data parameter
Jenis data parameter khusus untuk penyedia data .NET Framework. Menentukan jenis mengonversi nilai Parameter
ke jenis penyedia data .NET Framework sebelum meneruskan nilai ke sumber data. Anda juga dapat menentukan jenis Parameter
secara umum dengan menyetel properti DbType
dari objek Parameter
ke DbType tertentu.
Jenis penyedia data .NET Framework dari objek Parameter
disimpulkan dari jenis .NET Framework dari Value
objek Parameter
, atau dari DbType
objek Parameter
. Tabel berikut menunjukkan jenis Parameter
yang disimpulkan berdasarkan objek yang diteruskan sebagai nilai Parameter
atau DbType
yang ditentukan.
Jenis .NET Framework | DbType | SqlDbType | OleDbType | OdbcType | OracleType |
---|---|---|---|---|---|
Boolean | Boolean | Bit | Boolean | Bit | Byte |
Byte | Byte | TinyInt | UnsignedTinyInt | TinyInt | Byte |
byte[] | Biner | VarBinary. Konversi implisit ini akan gagal jika larik byte lebih besar dari ukuran maksimum VarBinary, yaitu 8000 byte. Untuk larik byte yang lebih besar dari 8000 byte, setel SqlDbType secara eksplisit. | VarBinary | Biner | Mentah |
Char | Menyimpulkan SqlDbType dari char tidak didukung. | Char | Char | Byte | |
DateTime | DateTime | DateTime | DBTimeStamp | DateTime | DateTime |
DateTimeOffset | DateTimeOffset | DateTimeOffset pada SQL Server 2008. Menyimpulkan SqlDbType dari DateTimeOffset tidak didukung dalam versi SQL Server yang lebih lama dari SQL Server 2008. | DateTime | ||
Decimal | Decimal | Decimal | Decimal | Numerik | Angka |
Double | Laju | Float | Laju | Laju | Laju |
Single | Tunggal | Riil | Tunggal | Riil | Float |
Guid | Guid | UniqueIdentifier | Guid | UniqueIdentifier | Mentah |
Int16 | Int16 | SmallInt | SmallInt | SmallInt | Int16 |
Int32 | Int32 | Int | Int | Int | Int32 |
Int64 | Int64 | Bigint | Bigint | Bigint | Angka |
Object | Objek | Varian | Varian | Menyimpulkan OdbcType dari Object tidak didukung. | Blob |
String | String | NVarChar. Konversi implisit ini akan gagal jika string lebih besar dari ukuran maksimum NVarChar, yaitu 4000 karakter. Untuk string yang lebih besar dari 4000 karakter, setel secara eksplisit SqlDbType. | VarWChar | NVarChar | NVarChar |
TimeSpan | Waktu | Waktu di SQL Server 2008. Menyimpulkan SqlDbType dari TimeSpan tidak didukung di versi SQL Server yang lebih lama dari SQL Server 2008. | DBTime | Waktu | DateTime |
UInt16 | UInt16 | Menyimpulkan SqlDbType dari UInt16 tidak didukung. | UnsignedSmallInt | Int | UInt16 |
UInt32 | UInt32 | Menyimpulkan SqlDbType dari UInt32 tidak didukung. | UnsignedInt | Bigint | UInt32 |
UInt64 | UInt64 | Menyimpulkan SqlDbType dari UInt64 tidak didukung. | UnsignedBigInt | Numerik | Angka |
AnsiString | VarChar | VarChar | VarChar | VarChar | |
AnsiStringFixedLength | Char | Char | Char | Char | |
Mata Uang | Uang | Mata Uang | Menyimpulkan OdbcType dari Currency tidak didukung. |
Angka | |
Tanggal | Tanggal di SQL Server 2008. Menyimpulkan SqlDbType dari Tanggal tidak didukung di versi SQL Server yang lebih lama dari SQL Server 2008. | DBDate | Tanggal | DateTime | |
SByte | Menyimpulkan SqlDbType dari SByte tidak didukung. | TinyInt | Menyimpulkan OdbcType dari SByte tidak didukung. |
SByte | |
StringFixedLength | NChar | WChar | NChar | NChar | |
Waktu | Waktu di SQL Server 2008. Menyimpulkan SqlDbType dari Waktu tidak didukung di versi SQL Server yang lebih lama dari SQL Server 2008. | DBTime | Waktu | DateTime | |
VarNumeric | Menyimpulkan SqlDbType dari VarNumeric tidak didukung. | VarNumeric | Menyimpulkan OdbcType dari VarNumeric tidak didukung. |
Angka | |
jenis yang ditentukan pengguna (objek dengan SqlUserDefinedAggregateAttribute | Objek atau String, tergantung penyedia (SqlClient selalu mengembalikan Objek, Odbc selalu mengembalikan String, dan penyedia data terkelola OleDb dapat melihat salah satu | SqlDbType.Udt jika SqlUserDefinedTypeAttribute ada, jika tidak, Varian | OleDbType.VarWChar (jika nilai null) jika tidak, OleDbType.Variant. | OdbcType.NVarChar | tidak didukung |
Catatan
Konversi dari desimal ke jenis lain mempersempit konversi yang membulatkan nilai desimal ke nilai integer terdekat menuju nol. Jika hasil konversi tidak dapat diwakili dalam jenis tujuan, maka OverflowException akan dilemparkan.
Catatan
Saat Anda mengirim nilai parameter nol ke server, Anda harus menentukan DBNull, bukan null
(Nothing
dalam Visual Basic). Nilai nol dalam sistem adalah objek kosong yang tidak memiliki nilai. DBNull digunakan untuk mewakili nilai null. Untuk informasi selengkapnya tentang null database, lihat Menangani Nilai Null.
Memperoleh informasi parameter
Parameter juga dapat berasal dari prosedur tersimpan menggunakan kelas DbCommandBuilder
. Baik kelas SqlCommandBuilder
dan OleDbCommandBuilder
menyediakan metode statis, DeriveParameters
, yang secara otomatis mengisi kumpulan parameter dari objek perintah yang menggunakan informasi parameter dari prosedur tersimpan. Perhatikan bahwa DeriveParameters
menimpa informasi parameter yang ada untuk perintah.
Catatan
Memperoleh informasi parameter dikenakan penalti kinerja karena memerlukan perjalanan pulang pergi tambahan ke sumber data untuk mengambil informasi. Jika informasi parameter diketahui pada waktu desain, Anda dapat meningkatkan kinerja aplikasi Anda dengan mengatur parameter secara eksplisit.
Untuk mendapatkan informasi selengkapnya, lihat Menghasilkan Perintah dengan CommandBuilders.
Menggunakan parameter dengan SqlCommand dan prosedur tersimpan
Prosedur tersimpan menawarkan banyak keuntungan dalam aplikasi berbasis data. Dengan menggunakan prosedur yang tersimpan, operasi database dapat dienkapsulasi dalam satu perintah, dioptimalkan untuk kinerja terbaik, dan ditingkatkan dengan keamanan tambahan. Meskipun prosedur tersimpan dapat dipanggil dengan meneruskan nama prosedur tersimpan diikuti dengan argumen parameter sebagai pernyataan SQL, dengan menggunakan kumpulan Parameters dari objek ADO.NET DbCommand memungkinkan Anda untuk secara lebih eksplisit mendefinisikan parameter prosedur tersimpan, dan untuk mengakses parameter keluaran dan mengembalikan nilai.
Catatan
Pernyataan berparameter dijalankan di server dengan menggunakan sp_executesql,
yang memungkinkan penggunaan kembali rencana kueri. Kursor atau variabel lokal dalam sp_executesql
batch tidak terlihat oleh batch yang memanggil sp_executesql
. Perubahan dalam konteks database hanya berlangsung hingga akhir pernyataan sp_executesql
. Untuk informasi selengkapnya, lihat sp_executesql (Transact-SQL).
Saat menggunakan parameter dengan SqlCommand untuk menjalankan prosedur tersimpan SQL Server, nama parameter yang ditambahkan ke koleksi Parameters harus cocok dengan nama penanda parameter dalam prosedur tersimpan. .NET Framework Data Provider untuk SQL Server tidak mendukung tanda tanya (?) tempat penampung untuk meneruskan parameter ke pernyataan SQL atau prosedur yang disimpan. Ini memperlakukan parameter dalam prosedur yang disimpan sebagai parameter bernama dan mencari penanda parameter yang cocok. Misalnya, prosedur tersimpan CustOrderHist
ditentukan dengan menggunakan parameter bernama @CustomerID
. Ketika kode Anda menjalankan prosedur tersimpan, kode juga harus menggunakan parameter bernama @CustomerID
.
CREATE PROCEDURE dbo.CustOrderHist @CustomerID varchar(5)
Contoh
Contoh ini menunjukkan cara memanggil prosedur tersimpan SQL Server di database sampel Northwind
. Nama prosedur tersimpan adalah dbo.SalesByCategory
dan memiliki parameter input bernama @CategoryName
dengan jenis data nvarchar(15)
. Kode membuat SqlConnection baru di dalam blok penggunaan sehingga koneksi dibuang saat prosedur berakhir. Objek SqlCommand dan SqlParameter dibuat, dan propertinya diatur. menjalankan SqlDataReader dan SqlCommand
mengembalikan set hasil dari prosedur tersimpan, menampilkan output di jendela konsol.
Catatan
Alih-alih membuat objek SqlCommand
dan SqlParameter
kemudian mengatur properti dalam pernyataan terpisah, Anda dapat memilih untuk menggunakan salah satu konstruktor yang kelebihan beban untuk mengatur beberapa properti dalam satu pernyataan.
static void GetSalesByCategory(string connectionString,
string categoryName)
{
using (SqlConnection connection = new(connectionString))
{
// Create the command and set its properties.
SqlCommand command = new()
{
Connection = connection,
CommandText = "SalesByCategory",
CommandType = CommandType.StoredProcedure
};
// Add the input parameter and set its properties.
SqlParameter parameter = new()
{
ParameterName = "@CategoryName",
SqlDbType = SqlDbType.NVarChar,
Direction = ParameterDirection.Input,
Value = categoryName
};
// Add the parameter to the Parameters collection.
command.Parameters.Add(parameter);
// Open the connection and execute the reader.
connection.Open();
using (SqlDataReader reader = command.ExecuteReader())
{
if (reader.HasRows)
{
while (reader.Read())
{
Console.WriteLine("{0}: {1:C}", reader[0], reader[1]);
}
}
else
{
Console.WriteLine("No rows found.");
}
reader.Close();
}
}
}
Shared Sub GetSalesByCategory(ByVal connectionString As String, _
ByVal categoryName As String)
Using connection As New SqlConnection(connectionString)
' Create the command and set its properties.
Dim command As SqlCommand = New SqlCommand()
command.Connection = connection
command.CommandText = "SalesByCategory"
command.CommandType = CommandType.StoredProcedure
' Add the input parameter and set its properties.
Dim parameter As New SqlParameter()
parameter.ParameterName = "@CategoryName"
parameter.SqlDbType = SqlDbType.NVarChar
parameter.Direction = ParameterDirection.Input
parameter.Value = categoryName
' Add the parameter to the Parameters collection.
command.Parameters.Add(parameter)
' Open the connection and execute the reader.
connection.Open()
Using reader As SqlDataReader = command.ExecuteReader()
If reader.HasRows Then
Do While reader.Read()
Console.WriteLine("{0}: {1:C}", _
reader(0), reader(1))
Loop
Else
Console.WriteLine("No rows returned.")
End If
End Using
End Using
End Sub
Menggunakan parameter dengan OleDbCommand atau OdbcCommand
Saat menggunakan parameter dengan OleDbCommand atau OdbcCommand, urutan parameter yang ditambahkan ke koleksi Parameters
harus sesuai dengan urutan parameter yang ditentukan dalam prosedur tersimpan Anda. .NET Framework Data Provider untuk OLE DB dan .NET Framework Data Provider untuk ODBC memperlakukan parameter dalam prosedur yang disimpan sebagai tempat penampung dan menerapkan nilai parameter secara berurutan. Selain itu, parameter nilai yang dikembalikan harus menjadi parameter pertama yang ditambahkan ke koleksi Parameters
.
.NET Framework Data Provider untuk OLE DB dan .NET Framework Data Provider untuk ODBC tidak mendukung parameter bernama untuk meneruskan parameter ke pernyataan SQL atau prosedur yang disimpan. Dalam hal ini, Anda harus menggunakan tempat penampung tanda tanya (?), seperti pada contoh berikut.
SELECT * FROM Customers WHERE CustomerID = ?
Akibatnya, urutan objek Parameter
yang ditambahkan ke koleksi Parameters
harus langsung sesuai dengan posisi ? tempat penampung untuk parameter.
Contoh OleDb
Dim command As OleDbCommand = New OleDbCommand( _
"SampleProc", connection)
command.CommandType = CommandType.StoredProcedure
Dim parameter As OleDbParameter = command.Parameters.Add( _
"RETURN_VALUE", OleDbType.Integer)
parameter.Direction = ParameterDirection.ReturnValue
parameter = command.Parameters.Add( _
"@InputParm", OleDbType.VarChar, 12)
parameter.Value = "Sample Value"
parameter = command.Parameters.Add( _
"@OutputParm", OleDbType.VarChar, 28)
parameter.Direction = ParameterDirection.Output
OleDbCommand command = new OleDbCommand("SampleProc", connection);
command.CommandType = CommandType.StoredProcedure;
OleDbParameter parameter = command.Parameters.Add(
"RETURN_VALUE", OleDbType.Integer);
parameter.Direction = ParameterDirection.ReturnValue;
parameter = command.Parameters.Add(
"@InputParm", OleDbType.VarChar, 12);
parameter.Value = "Sample Value";
parameter = command.Parameters.Add(
"@OutputParm", OleDbType.VarChar, 28);
parameter.Direction = ParameterDirection.Output;
Contoh Odbc
Dim command As OdbcCommand = New OdbcCommand( _
"{ ? = CALL SampleProc(?, ?) }", connection)
command.CommandType = CommandType.StoredProcedure
Dim parameter As OdbcParameter = command.Parameters.Add("RETURN_VALUE", OdbcType.Int)
parameter.Direction = ParameterDirection.ReturnValue
parameter = command.Parameters.Add( _
"@InputParm", OdbcType.VarChar, 12)
parameter.Value = "Sample Value"
parameter = command.Parameters.Add( _
"@OutputParm", OdbcType.VarChar, 28)
parameter.Direction = ParameterDirection.Output
OdbcCommand command = new OdbcCommand( _
"{ ? = CALL SampleProc(?, ?) }", connection);
command.CommandType = CommandType.StoredProcedure;
OdbcParameter parameter = command.Parameters.Add( _
"RETURN_VALUE", OdbcType.Int);
parameter.Direction = ParameterDirection.ReturnValue;
parameter = command.Parameters.Add( _
"@InputParm", OdbcType.VarChar, 12);
parameter.Value = "Sample Value";
parameter = command.Parameters.Add( _
"@OutputParm", OdbcType.VarChar, 28);
parameter.Direction = ParameterDirection.Output;