Saya sangat baru dalam bekerja dengan database. Sekarang saya bisa menulis SELECT
, UPDATE
, DELETE
, dan INSERT
perintah. Tetapi saya telah melihat banyak forum tempat kami lebih suka menulis:
SELECT empSalary from employee where salary = @salary
...dari pada:
SELECT empSalary from employee where salary = txtSalary.Text
Mengapa kami selalu lebih suka menggunakan parameter dan bagaimana saya akan menggunakannya?
Saya ingin tahu kegunaan dan manfaat dari metode pertama. Saya bahkan pernah mendengar tentang injeksi SQL tetapi saya tidak sepenuhnya memahaminya. Saya bahkan tidak tahu apakah injeksi SQL terkait dengan pertanyaan saya.
sql
sql-server
sql-injection
Sandy
sumber
sumber
Jawaban:
Menggunakan parameter membantu mencegah serangan SQL Injection saat database digunakan bersama dengan antarmuka program seperti program desktop atau situs web.
Dalam contoh Anda, pengguna dapat langsung menjalankan kode SQL di database Anda dengan membuat pernyataan di
txtSalary
.Misalnya, jika mereka menulis
0 OR 1=1
, SQL yang akan dieksekusi adalahdimana semua gaji kaisar akan dikembalikan.
Lebih lanjut, pengguna dapat melakukan perintah yang jauh lebih buruk terhadap database Anda, termasuk menghapusnya jika mereka menulis
0; Drop Table employee
:Tabel
employee
tersebut kemudian akan dihapus.Dalam kasus Anda, sepertinya Anda menggunakan .NET. Menggunakan parameter semudah:
C #
VB.NET
Edit 2016-4-25:
Sesuai komentar George Stocker, saya mengubah kode sampel agar tidak digunakan
AddWithValue
. Juga, secara umum disarankan agar Anda membungkusIDisposable
s dalamusing
pernyataan.sumber
Insert Into table (Col1, Col2) Values (@Col1, @Col2)
. Dalam kode Anda, Anda akan menambahkan beberapaAddWithValue
s.parameter.Value = someValue
.Anda benar, ini terkait dengan injeksi SQL , yang merupakan kerentanan yang memungkinkan pengguna malicioius untuk mengeksekusi pernyataan sewenang-wenang terhadap database Anda. Komik XKCD favorit jaman dulu ini menggambarkan konsepnya:
Dalam contoh Anda, jika Anda hanya menggunakan:
Anda terbuka untuk injeksi SQL. Misalnya, seseorang memasukkan txtSalary:
Saat Anda menjalankan kueri ini, kueri akan melakukan a
SELECT
dan anUPDATE
atauDROP
, atau apa pun yang mereka inginkan. Bagian--
akhir hanya mengomentari sisa kueri Anda, yang akan berguna dalam serangan jika Anda menggabungkan apa pun setelahnyatxtSalary.Text
.Cara yang benar adalah dengan menggunakan kueri berparameter, misalnya (C #):
Dengan itu, Anda dapat menjalankan kueri dengan aman.
Untuk referensi tentang cara menghindari injeksi SQL dalam beberapa bahasa lain, periksa bobby-tables.com , situs web yang dikelola oleh pengguna SO .
sumber
Selain jawaban lain perlu menambahkan bahwa parameter tidak hanya membantu mencegah injeksi sql tetapi dapat meningkatkan kinerja query . Caching server Sql paket kueri berparameter dan menggunakannya kembali pada eksekusi kueri berulang. Jika Anda tidak membuat parameter kueri Anda, maka sql server akan menyusun rencana baru pada setiap eksekusi kueri (dengan beberapa pengecualian) jika teks kueri berbeda.
Informasi selengkapnya tentang caching paket kueri
sumber
Dua tahun setelah perjalanan pertamaku , aku sedang memulihkan ...
Mengapa kami lebih memilih parameter? Injeksi SQL jelas merupakan alasan besar, tetapi mungkinkah kita diam-diam ingin kembali ke SQL sebagai bahasa . SQL dalam literal string sudah menjadi praktik budaya yang aneh, tetapi setidaknya Anda dapat menyalin dan menempel permintaan Anda ke studio manajemen. SQL dibangun secara dinamis dengan kondisional bahasa host dan struktur kontrol, ketika SQL memiliki kondisional dan struktur kontrol, hanyalah barbarisme level 0. Anda harus menjalankan aplikasi Anda dalam debug, atau dengan jejak, untuk melihat SQL apa yang dihasilkannya.
Jangan berhenti hanya dengan parameter. Pergi jauh-jauh dan gunakan QueryFirst (disclaimer: yang saya tulis). SQL Anda berada dalam file .sql. Anda mengeditnya di jendela editor TSQL yang luar biasa, dengan validasi sintaks dan Intellisense untuk tabel dan kolom Anda. Anda dapat menetapkan data uji di bagian komentar khusus dan klik "putar" untuk menjalankan kueri Anda tepat di jendela tersebut. Membuat parameter semudah memasukkan "@myParam" di SQL Anda. Kemudian, setiap kali Anda menyimpan, QueryFirst menghasilkan pembungkus C # untuk kueri Anda. Parameter Anda muncul, diketik dengan kuat, sebagai argumen untuk metode Execute (). Hasil Anda dikembalikan dalam IEnumerable atau Daftar POCO yang diketik dengan kuat, jenis yang dihasilkan dari skema aktual yang dikembalikan oleh kueri Anda. Jika kueri Anda tidak berjalan, aplikasi Anda tidak akan dikompilasi. Jika skema db Anda berubah dan kueri Anda berjalan tetapi beberapa kolom hilang, kesalahan kompilasi mengarah ke baris dalam kode Andayang mencoba mengakses data yang hilang. Dan masih banyak keuntungan lainnya. Mengapa Anda ingin mengakses data dengan cara lain?
sumber
Di Sql ketika ada kata yang mengandung tanda @ artinya itu adalah variabel dan kami menggunakan variabel ini untuk menetapkan nilai di dalamnya dan menggunakannya di area bilangan pada skrip sql yang sama karena hanya dibatasi pada satu skrip sementara Anda dapat mendeklarasikan banyak variabel dari jenis dan nama yang sama pada banyak skrip. Kami menggunakan variabel ini dalam lot prosedur tersimpan karena prosedur tersimpan adalah kueri yang telah dikompilasi sebelumnya dan kami dapat mengirimkan nilai dalam variabel ini dari skrip, desktop, dan situs web untuk informasi lebih lanjut, baca Menyatakan Variabel Lokal , Prosedur Tersimpan Sql , dan injeksi sql .
Baca juga Lindungi dari injeksi sql, ini akan memandu bagaimana Anda dapat melindungi database Anda.
Semoga membantu Anda untuk memahami juga pertanyaan apa pun, komentar saya.
sumber
Jawaban lain mencakup mengapa parameter itu penting, tetapi ada sisi negatifnya! Dalam .net, ada beberapa metode untuk membuat parameter (Add, AddWithValue), tetapi semuanya mengharuskan Anda untuk khawatir, tidak perlu, tentang nama parameter, dan semuanya mengurangi keterbacaan SQL dalam kode. Tepat ketika Anda mencoba untuk merenungkan SQL, Anda perlu mencari di atas atau di bawah untuk melihat nilai apa yang telah digunakan dalam parameter.
Saya dengan rendah hati mengklaim kelas SqlBuilder kecil saya adalah cara paling elegan untuk menulis kueri berparameter . Kode Anda akan terlihat seperti ini ...
C #
Kode Anda akan lebih pendek dan lebih mudah dibaca. Anda bahkan tidak memerlukan baris tambahan, dan, saat Anda membaca kembali, Anda tidak perlu mencari-cari nilai parameter. Kelas yang Anda butuhkan ada di sini ...
sumber
AddWithValue
dapat menyebabkan masalah konversi implisit.Pos lama tetapi ingin memastikan pendatang baru mengetahui prosedur Tersimpan .
Nilai 10 ¢ saya di sini adalah bahwa jika Anda dapat menulis pernyataan SQL Anda sebagai prosedur yang tersimpan , menurut pandangan saya adalah pendekatan yang optimal. Saya SELALU menggunakan procs yang tersimpan dan tidak pernah mengulang catatan dalam kode utama saya. Untuk Contoh:
SQL Table > SQL Stored Procedures > IIS/Dot.NET > Class
.Saat Anda menggunakan prosedur tersimpan, Anda dapat membatasi pengguna hanya untuk JALANKAN izin, sehingga mengurangi risiko keamanan .
Prosedur tersimpan Anda secara inheren diparamerisasi, dan Anda dapat menentukan parameter input dan output.
Prosedur yang tersimpan (jika mengembalikan data melalui
SELECT
pernyataan) dapat diakses dan dibaca dengan cara yang sama persis seperti yang Anda lakukan padaSELECT
pernyataan biasa dalam kode Anda.Ini juga berjalan lebih cepat karena dikompilasi di SQL Server.
Apakah saya juga menyebutkan Anda dapat melakukan beberapa langkah, misalnya
update
tabel, memeriksa nilai di server DB lain, dan kemudian setelah selesai, mengembalikan data ke klien, semua di server yang sama, dan tidak ada interaksi dengan klien. Jadi ini JAUH lebih cepat daripada mengkodekan logika ini dalam kode Anda.sumber