Apakah dianggap sebagai pola anti untuk hardcode SQL ke dalam aplikasi seperti ini:
public List<int> getPersonIDs()
{
List<int> listPersonIDs = new List<int>();
using (SqlConnection connection = new SqlConnection(
ConfigurationManager.ConnectionStrings["Connection"].ConnectionString))
using (SqlCommand command = new SqlCommand())
{
command.CommandText = "select id from Person";
command.Connection = connection;
connection.Open();
SqlDataReader datareader = command.ExecuteReader();
while (datareader.Read())
{
listPersonIDs.Add(Convert.ToInt32(datareader["ID"]));
}
}
return listPersonIDs;
}
Saya biasanya memiliki layer repositori dll, tetapi saya telah mengecualikannya dalam kode di atas untuk kesederhanaan.
Baru-baru ini saya mendapat umpan balik dari seorang kolega yang mengeluh bahwa SQL ditulis dalam kode sumber. Saya tidak mendapatkan kesempatan untuk bertanya mengapa dan dia sekarang pergi selama dua minggu (mungkin lebih). Saya berasumsi bahwa yang ia maksudkan adalah:
- Gunakan LINQ
atau - Gunakan prosedur tersimpan untuk SQL
Apakah saya benar? Apakah dianggap sebagai pola anti untuk menulis SQL dalam kode sumber? Kami adalah tim kecil yang mengerjakan proyek ini. Manfaat dari prosedur tersimpan menurut saya adalah bahwa Pengembang SQL dapat terlibat dengan proses pengembangan (menulis prosedur tersimpan dll).
Sunting Tautan berikut berbicara tentang pernyataan SQL yang dikodekan: https://docs.microsoft.com/en-us/sql/odbc/reference/develop-app/hard-coded-sql-statements . Apakah ada manfaat mempersiapkan pernyataan SQL?
Jawaban:
Anda mengecualikan bagian penting untuk kesederhanaan. Repositori adalah lapisan abstraksi untuk kegigihan. Kami memisahkan kegigihan ke dalam lapisannya sendiri sehingga kami dapat mengubah teknologi kegigihan dengan lebih mudah saat dibutuhkan. Oleh karena itu, memiliki SQL di luar lapisan kegigihan sepenuhnya menggagalkan upaya memiliki lapisan kegigihan terpisah.
Sebagai hasilnya: SQL baik-baik saja di dalam lapisan ketekunan yang khusus untuk teknologi SQL (misalnya SQL baik-baik saja dalam
SQLCustomerRepository
tetapi tidak dalam aMongoCustomerRepository
). Di luar lapisan kegigihan, SQL memecah abstraksi Anda dan karenanya dianggap praktik yang sangat buruk (oleh saya).Adapun alat-alat seperti LINQ atau JPQL: Itu hanya bisa abstrak rasa SQL di luar sana. Memiliki kueri LINQ-Code atau JPQL di luar repositori memecah abstraksi persistensi seperti halnya SQL mentah.
Keuntungan besar lainnya dari lapisan persistensi terpisah adalah bahwa ia memungkinkan Anda untuk melepaskan kode logika bisnis Anda tanpa harus menyiapkan server DB.
Anda mendapatkan tes unit-profil rendah-memori yang cepat dengan hasil yang dapat direproduksi di semua platform yang didukung bahasa Anda.
Dalam arsitektur Layanan MVC + ini adalah tugas sederhana mengejek instance repositori, membuat beberapa data tiruan dalam memori dan menentukan bahwa repositori harus mengembalikan data tiruan itu ketika pengambil tertentu dipanggil. Anda kemudian dapat menetapkan data uji per unittest dan tidak khawatir tentang membersihkan DB sesudahnya.
Pengujian menulis ke DB sesederhana: memverifikasi bahwa metode pembaruan yang relevan pada lapisan persistensi telah dipanggil dan menyatakan bahwa entitas berada dalam keadaan yang benar ketika itu terjadi.
sumber
Sebagian besar aplikasi bisnis standar saat ini menggunakan lapisan yang berbeda dengan tanggung jawab yang berbeda. Namun, lapisan mana yang Anda gunakan untuk aplikasi Anda , dan lapisan mana yang memiliki tanggung jawab terserah Anda dan tim Anda. Sebelum Anda dapat membuat keputusan tentang apakah benar atau salah untuk menempatkan SQL secara langsung dalam fungsi yang Anda tunjukkan kepada kami, Anda perlu tahu
lapisan mana dalam aplikasi Anda yang memiliki tanggung jawab apa
dari mana lapisan fungsi di atas adalah dari
Tidak ada solusi "satu ukuran untuk semua" untuk ini. Dalam beberapa aplikasi, perancang lebih suka menggunakan kerangka kerja ORM dan membiarkan kerangka tersebut menghasilkan semua SQL. Dalam beberapa aplikasi, perancang lebih suka menyimpan SQL semacam itu secara eksklusif dalam prosedur tersimpan. Untuk beberapa aplikasi ada lapisan ketekunan (atau repositori) yang ditulis tangan di mana SQL hidup, dan untuk aplikasi lain tidak apa-apa untuk menentukan pengecualian dalam keadaan tertentu dari secara ketat menempatkan SQL dalam lapisan ketekunan tersebut.
Jadi apa yang perlu Anda pikirkan: lapisan mana yang Anda inginkan atau butuhkan dalam aplikasi khusus Anda, dan bagaimana Anda menginginkan tanggung jawab? Anda menulis "Saya biasanya memiliki lapisan repositori" , tetapi apa tanggung jawab pasti yang ingin Anda miliki di dalam lapisan itu, dan tanggung jawab apa yang ingin Anda tempatkan di tempat lain? Jawab itu dulu, lalu kamu bisa jawab sendiri.
sumber
Marstato memberikan jawaban yang bagus tetapi saya ingin menambahkan beberapa komentar lagi.
SQL in source BUKAN anti-pola tetapi dapat menyebabkan masalah. Saya ingat ketika Anda dulu harus memasukkan pertanyaan SQL ke dalam properti komponen yang dijatuhkan ke setiap bentuk. Itu membuat segalanya menjadi sangat buruk dengan sangat cepat dan Anda harus melompati lingkaran untuk menemukan pertanyaan. Saya menjadi pendukung kuat untuk memusatkan akses Database sebanyak mungkin dalam keterbatasan bahasa yang saya gunakan. Rekan Anda mungkin mendapatkan kilas balik ke hari-hari kelam ini.
Sekarang, beberapa komentar berbicara tentang penguncian vendor seperti itu secara otomatis adalah hal yang buruk. Bukan itu. Jika saya menandatangani enam angka setiap tahun untuk menggunakan Oracle, Anda dapat bertaruh bahwa saya ingin aplikasi apa pun yang mengakses database menggunakan sintaks Oracle tambahan dengan tepat.tetapi untuk sepenuhnya. Saya tidak akan senang jika database mengkilap saya dilumpuhkan oleh coders yang menulis vanilla ANSI SQL dengan buruk ketika ada "cara Oracle" dalam menulis SQL yang tidak melumpuhkan database. Ya, mengubah basis data akan lebih sulit tetapi saya hanya melihatnya dilakukan di situs klien besar beberapa kali dalam lebih dari 20 tahun dan salah satu dari kasus tersebut berpindah dari DB2 -> Oracle karena mainframe yang meng-host DB2 sudah usang dan dinonaktifkan. . Ya itu adalah vendor lock-in tetapi untuk pelanggan korporat sebenarnya diinginkan untuk membayar RDBMS yang mampu mahal seperti Oracle atau Microsoft SQL Server dan kemudian menggunakannya sepenuhnya. Anda memiliki perjanjian dukungan sebagai selimut kenyamanan Anda. Jika saya membayar untuk database dengan implementasi prosedur tersimpan yang kaya,
Ini mengarah ke titik berikutnya, jika Anda menulis aplikasi yang mengakses Database SQL Anda harus belajar SQL serta bahasa lain dan dengan belajar, maksud saya optimasi permintaan juga; Saya akan marah dengan Anda jika Anda menulis kode generasi SQL yang mem-flush cache SQL dengan rentetan pertanyaan yang hampir sama ketika Anda bisa menggunakan satu query parameterised secara cerdik.
Tidak ada alasan, tidak ada bersembunyi di balik dinding Hibernate. ORM yang digunakan dengan buruk benar - benar dapat melumpuhkan kinerja aplikasi. Saya ingat pernah melihat pertanyaan tentang Stack Overflow beberapa tahun yang lalu di sepanjang baris:
Bagaimana dengan "UPDATE tabel SET field1 = di mana field2 Benar dan Field3> 100". Membuat dan membuang 250.000 objek mungkin menjadi masalah Anda ...
yaitu Abaikan Hibernate ketika itu tidak tepat untuk menggunakannya. Pahami basis datanya.
Jadi, dalam ringkasan, menanamkan SQL dalam kode bisa menjadi praktik yang buruk tetapi ada banyak hal yang lebih buruk yang akhirnya bisa Anda lakukan untuk menghindari menanamkan SQL.
sumber
Ya, hard coding string SQL ke dalam kode aplikasi umumnya adalah anti-pola.
Mari kita coba kesampingkan toleransi yang telah kita kembangkan sejak bertahun-tahun melihat ini dalam kode produksi. Mencampur bahasa yang sama sekali berbeda dengan sintaks yang berbeda dalam file yang sama pada umumnya bukan teknik pengembangan yang diinginkan. Ini berbeda dari bahasa templat seperti Razor yang dirancang untuk memberikan makna kontekstual ke beberapa bahasa. Seperti Sava B. menyebutkan dalam komentar di bawah ini, SQL dalam bahasa C # atau bahasa aplikasi lainnya (Python, C ++, dll.) Adalah string seperti yang lainnya dan secara semantik tidak berarti. Hal yang sama berlaku ketika mencampur lebih dari satu bahasa dalam banyak kasus, meskipun ada situasi yang jelas di mana hal tersebut dapat diterima, seperti perakitan inline dalam C, potongan kecil dan komprehensif CSS dalam HTML (mencatat bahwa CSS dirancang untuk dicampur dengan HTML ), dan lain-lain.
(Robert C. Martin tentang bahasa campuran, Clean Code , Bab 17, "Code Smells and Heuristics", halaman 288)
Untuk tanggapan ini, saya akan memfokuskan SQL (seperti yang ditanyakan dalam pertanyaan). Masalah-masalah berikut ini dapat terjadi ketika menyimpan SQL sebagai rangkaian string yang dipisahkan:
@
Awalan C # membuat ini lebih mudah, tapi saya telah melihat banyak kode yang mengutip setiap baris SQL dan lolos dari baris baru."SELECT col1, col2...colN"\ "FROM painfulExample"\ "WHERE maintainability IS NULL"\ "AND modification.effort > @necessary"\
ORM penuh (Pemetaan Objek-Relasional seperti Entity Framework atau Hibernate) dapat menghilangkan SQL yang dibumbui secara acak dalam kode aplikasi. Penggunaan SQL dan file sumber daya saya hanyalah sebuah contoh. ORM, kelas pembantu, dll. Semuanya dapat membantu mencapai tujuan kode bersih.
Seperti yang dikatakan Kevin dalam jawaban sebelumnya, SQL dalam kode dapat diterima dalam proyek-proyek kecil, tetapi proyek besar dimulai sebagai proyek kecil, dan probabilitas sebagian besar tim akan kembali dan melakukannya dengan benar sering berbanding terbalik dengan ukuran kode.
Ada banyak cara sederhana untuk menjaga SQL dalam suatu proyek. Salah satu metode yang sering saya gunakan adalah untuk menempatkan setiap pernyataan SQL ke dalam file sumber daya Visual Studio, biasanya bernama "sql". File teks, dokumen JSON, atau sumber data lain mungkin masuk akal tergantung pada alat Anda. Dalam beberapa kasus, kelas terpisah yang didedikasikan untuk mengamankan string SQL mungkin merupakan pilihan terbaik, tetapi bisa memiliki beberapa masalah yang dijelaskan di atas.
Contoh SQL: Mana yang terlihat lebih elegan ?:
Menjadi
SQL selalu dalam file yang mudah ditemukan atau kumpulan file, masing-masing dengan nama deskriptif yang menggambarkan apa yang dilakukannya daripada bagaimana melakukannya, masing-masing dengan ruang untuk komentar yang tidak akan mengganggu aliran kode aplikasi :
Metode sederhana ini mengeksekusi kueri soliter. Dalam pengalaman saya, skala manfaat sebagai penggunaan "bahasa asing" tumbuh lebih canggih. Penggunaan file sumber daya oleh saya hanyalah sebuah contoh. Metode yang berbeda mungkin lebih tepat tergantung pada bahasa (SQL dalam kasus ini) dan platform.
Ini dan metode lain menyelesaikan daftar di atas dengan cara berikut:
SQL
.return SqlResource.DoTheThing;
Benar, implementasi ini dapat melewati sumber daya dan berisi SQL dalam sebuah string, tetapi beberapa (tidak semua) masalah di atas masih akan muncul.sql.GetOrdersForAccount
daripada lebih tumpulSELECT ... FROM ... WHERE...
Pembuatan SQL dalam suatu sumber daya cepat, sehingga ada sedikit dorongan untuk mencampur penggunaan sumber daya dengan SQL-in-code.
Terlepas dari metode yang dipilih, saya telah menemukan bahwa bahasa campuran biasanya mengurangi kualitas kode. Saya berharap bahwa beberapa masalah dan solusi yang dijelaskan di sini membantu pengembang menghilangkan bau kode ini bila perlu.
sumber
Tergantung. Ada sejumlah pendekatan berbeda yang dapat bekerja:
Seperti yang sering terjadi, jika proyek Anda telah memilih salah satu dari teknik ini, Anda harus konsisten dengan sisa proyek.
(1) dan (3) keduanya relatif baik dalam menjaga independensi antara logika aplikasi dan database, dalam arti bahwa aplikasi akan terus mengkompilasi dan lulus tes asap dasar jika Anda mengganti database dengan vendor yang berbeda. Namun, sebagian besar vendor tidak sepenuhnya sesuai dengan standar SQL, jadi mengganti vendor dengan vendor lain cenderung membutuhkan pengujian ekstensif dan pencarian bug terlepas dari teknik apa yang Anda gunakan. Saya ragu bahwa ini adalah masalah besar seperti yang dilakukan orang. Mengubah database pada dasarnya adalah pilihan terakhir ketika Anda tidak bisa mendapatkan database saat ini untuk memenuhi kebutuhan Anda. Jika itu terjadi, Anda mungkin memilih basis data dengan buruk.
Pilihan antara (1) dan (3) sebagian besar masalah seberapa besar Anda menyukai ORM. Menurut saya mereka terlalu sering digunakan. Mereka adalah representasi yang buruk dari model data relasional, karena baris tidak memiliki identitas dengan cara benda memiliki identitas. Anda kemungkinan akan menghadapi titik-titik rasa sakit di sekitar kendala unik, bergabung, dan Anda mungkin mengalami kesulitan mengungkapkan beberapa pertanyaan yang lebih rumit tergantung pada kekuatan ORM. Di sisi lain, (1) mungkin akan memerlukan kode lebih banyak daripada ORM.
(2) jarang terlihat, dalam pengalaman saya. Masalahnya adalah bahwa banyak toko melarang SWE untuk secara langsung memodifikasi skema basis data (karena "itulah tugas DBA"). Ini belum tentu merupakan Hal Buruk dalam dirinya sendiri; perubahan skema memiliki potensi signifikan untuk memecahkan hal-hal dan mungkin perlu diluncurkan dengan hati-hati. Namun, agar (2) berfungsi, SWE setidaknya harus dapat memperkenalkan pandangan baru dan memodifikasi pertanyaan dukungan dari pandangan yang ada dengan birokrasi minimal atau tanpa birokrasi. Jika ini tidak terjadi di tempat kerja Anda, (2) mungkin tidak akan bekerja untuk Anda.
Di sisi lain, jika Anda dapat membuat (2) bekerja, itu jauh lebih baik daripada kebanyakan solusi lain karena itu menjaga logika relasional dalam SQL daripada kode aplikasi. Tidak seperti bahasa pemrograman tujuan umum, SQL secara khusus dirancang untuk model data relasional, dan karenanya lebih baik dalam mengekspresikan pertanyaan dan transformasi data yang rumit. Tampilan juga dapat porting bersama dengan skema Anda saat mengubah database, tetapi mereka akan membuat gerakan seperti itu lebih rumit.
Untuk dibaca, prosedur tersimpan pada dasarnya hanya versi crappier (2). Saya tidak merekomendasikan mereka dalam kapasitas itu, tetapi Anda mungkin masih ingin mereka untuk menulis, jika database Anda tidak mendukung tampilan yang dapat diupdate , atau jika Anda perlu melakukan sesuatu yang lebih kompleks daripada memasukkan atau memperbarui satu baris pada suatu waktu (mis. transaksi, baca-lalu-tulis, dll.). Anda dapat memasangkan prosedur tersimpan Anda ke tampilan menggunakan pemicu (yaitu
CREATE TRIGGER trigger_name INSTEAD OF INSERT ON view_name FOR EACH ROW EXECUTE PROCEDURE procedure_name;
), tetapi pendapat sangat bervariasi, apakah ini sebenarnya Ide yang Baik. Pemrakarsa akan memberi tahu Anda bahwa ini membuat SQL yang dijalankan aplikasi Anda sesederhana mungkin. Para pencela akan memberi tahu Anda bahwa ini adalah tingkat "sihir" yang tidak dapat diterima dan bahwa Anda harus menjalankan prosedur langsung dari aplikasi Anda. Aku akan mengatakan ini adalah ide yang baik jika prosedur Anda disimpan terlihat atau bertindak banyak sepertiINSERT
,UPDATE
, atauDELETE
, dan ide buruk jika melakukan sesuatu yang lain. Pada akhirnya Anda harus memutuskan sendiri gaya mana yang lebih masuk akal.(4) adalah solusinya. Mungkin layak untuk proyek kecil, atau yang besar yang hanya berinteraksi secara sporadis dengan database. Tetapi untuk proyek-proyek dengan banyak SQL, itu bukan ide yang baik karena Anda mungkin memiliki duplikat atau variasi permintaan yang sama tersebar di sekitar aplikasi Anda secara sembarangan, yang mengganggu keterbacaan dan refactoring.
sumber
Belum tentu. Jika Anda membaca semua komentar di sini, Anda akan menemukan argumen yang valid untuk pernyataan SQL hardcoding dalam kode sumber.
Masalahnya ada pada di mana Anda menempatkan pernyataan . Jika Anda menempatkan pernyataan SQL di seluruh proyek, di mana-mana, Anda mungkin akan mengabaikan beberapa prinsip SOLID yang biasanya kami berusaha untuk ikuti.
Kita tidak bisa mengatakan apa yang dia maksudkan. Namun, kita bisa menebaknya. Misalnya, hal pertama yang muncul di benak saya adalah vendor lock-in . Pernyataan SQL Hardcoding dapat mengarahkan Anda untuk memadukan aplikasi Anda dengan ketat ke mesin DB. Misalnya, menggunakan fungsi spesifik vendor yang tidak sesuai dengan ANSI.
Ini tidak selalu salah atau buruk. Saya hanya menunjuk fakta.
Mengabaikan prinsip SOLID dan kunci vendor memiliki kemungkinan konsekuensi buruk yang mungkin Anda abaikan. Itu sebabnya biasanya baik untuk duduk bersama tim dan mengungkapkan keraguan Anda.
Saya pikir ini tidak ada hubungannya dengan keuntungan dari prosedur tersimpan. Selain itu, jika kolega Anda tidak menyukai hardcoded SQL, Kemungkinan memindahkan bisnis ke prosedur tersimpan akan membencinya juga.
Iya. Pos tersebut menambahkan keuntungan dari pernyataan yang disiapkan . Ini semacam SQL templating. Lebih aman daripada rangkaian senar. Tetapi postingan itu tidak mendorong Anda untuk pergi dengan cara ini atau menegaskan bahwa Anda benar. Itu hanya menjelaskan bagaimana kita dapat menggunakan hardcoded SQL dengan cara yang aman dan efisien.
Ringkasnya, coba tanyakan dulu pada kolega Anda. Kirim email, telepon dia, ... Entah dia menjawab atau tidak, duduklah bersama tim dan singkapkan keraguan Anda. Temukan solusi yang paling sesuai dengan kebutuhan Anda. Jangan membuat asumsi yang salah berdasarkan apa yang Anda baca di sana.
sumber
select GETDATE(), ....
GETDATE () adalah fungsi tanggal SqlServer. Di mesin lain, fungsinya memiliki nama berbeda, ekspresi berbeda, ...Saya pikir ini praktik yang buruk, ya. Orang lain telah menunjukkan keunggulan menjaga semua kode akses data Anda di lapisannya sendiri. Anda tidak perlu mencari-cari, lebih mudah untuk mengoptimalkan dan menguji ... Tetapi bahkan di dalam lapisan itu, Anda memiliki beberapa pilihan: menggunakan ORM, gunakan sprocs, atau sematkan query SQL sebagai string. Saya akan mengatakan string query SQL sejauh ini merupakan pilihan terburuk.
Dengan ORM, pengembangan menjadi jauh lebih mudah, dan lebih sedikit rawan kesalahan. Dengan EF, Anda mendefinisikan skema Anda hanya dengan membuat kelas model Anda (Anda tetap harus membuat kelas-kelas ini). Meminta pertanyaan dengan LINQ sangat mudah - Anda sering lolos dengan 2 baris c # di mana Anda harus menulis dan memelihara sproc. IMO, ini memiliki keuntungan besar dalam hal produktivitas dan pemeliharaan - kode lebih sedikit, lebih sedikit masalah. Tetapi ada overhead kinerja, bahkan jika Anda tahu apa yang Anda lakukan.
Sprocs (atau fungsi) adalah pilihan lain. Di sini, Anda menulis kueri SQL secara manual. Tetapi setidaknya Anda mendapatkan jaminan bahwa mereka benar. Jika Anda bekerja di .NET, Visual Studio bahkan akan membuat kesalahan kompilator jika SQL tidak valid. Ini bagus. Jika Anda mengubah atau menghapus beberapa kolom, dan beberapa pertanyaan Anda menjadi tidak valid, setidaknya Anda akan mengetahuinya selama waktu kompilasi. Ini juga jauh lebih mudah untuk mempertahankan sprocs dalam file mereka sendiri - Anda mungkin akan mendapatkan penyorotan sintaksis, autocomplete..etc.
Jika kueri disimpan sebagai sprocs, Anda juga dapat mengubahnya tanpa mengompilasi ulang dan menggunakan kembali aplikasi. Jika Anda melihat bahwa sesuatu dalam SQL Anda rusak, DBA dapat memperbaikinya tanpa perlu memiliki akses ke kode aplikasi Anda. Secara umum, jika kueri Anda dalam string literal, Anda dbas tidak bisa melakukan pekerjaan mereka dengan mudah.
Query SQL sebagai string literal juga akan membuat akses data Anda # kode kurang dibaca.
Sama seperti aturan praktis, konstanta sihir juga buruk. Itu termasuk string literal.
sumber
Ini bukan anti-pola (jawaban ini berbahaya bagi pendapat). Tetapi pemformatan kode itu penting, dan string SQL harus diformat sehingga jelas terpisah dari kode yang menggunakannya. Sebagai contoh
sumber
Saya tidak bisa memberi tahu Anda apa yang dimaksud rekan kerja Anda. Tapi saya bisa menjawab ini:
Ya . Menggunakan pernyataan yang disiapkan dengan variabel terikat adalah pertahanan yang disarankan terhadap injeksi SQL , yang tetap menjadi risiko keamanan tunggal terbesar untuk aplikasi web selama lebih dari satu dekade . Serangan ini sangat umum sehingga ditampilkan dalam komik web hampir sepuluh tahun yang lalu, dan sudah saatnya pertahanan efektif dikerahkan.
... dan pertahanan paling efektif terhadap rangkaian string kueri yang buruk tidak mewakili kueri sebagai string, tetapi untuk menggunakan API kueri tipe-aman untuk membangun kueri. Sebagai contoh, berikut adalah cara saya menulis permintaan Anda di Java dengan QueryDSL:
Seperti yang Anda lihat, tidak ada string tunggal literal di sini, membuat injeksi SQL meringkas. Selain itu, saya memiliki penyelesaian kode saat menulis ini, dan IDE saya dapat melakukan refactor jika saya memilih untuk mengganti nama kolom id. Juga, saya dapat dengan mudah menemukan semua kueri untuk tabel orang dengan menanyakan IDE saya di mana
person
variabel diakses. Oh, dan apakah Anda memperhatikan itu sedikit lebih pendek dan lebih mudah di mata daripada kode Anda?Saya hanya dapat berasumsi bahwa sesuatu seperti ini juga tersedia untuk C #. Sebagai contoh, saya mendengar hal-hal hebat tentang LINQ.
Singkatnya, merepresentasikan kueri sebagai string SQL menyulitkan IDE untuk secara bermakna membantu dalam penulisan dan refactoring kueri, menolak deteksi sintaksis dan mengetik kesalahan dari waktu kompilasi untuk menjalankan waktu, dan merupakan penyebab utama kerentanan injeksi SQL [1]. Jadi ya, ada alasan yang sah mengapa seseorang mungkin tidak ingin string SQL dalam kode sumber.
[1]: Ya, penggunaan pernyataan yang dipersiapkan dengan benar juga mencegah injeksi SQL. Tapi itu jawaban lain di utas ini rentan terhadap injeksi SQL sampai komentator menunjukkan ini tidak menginspirasi kepercayaan pada programmer junior dengan benar menggunakannya kapanpun diperlukan ...
sumber
Banyak jawaban bagus di sini. Terlepas dari apa yang telah dikatakan, saya ingin menambahkan satu hal lagi.
Saya tidak mempertimbangkan menggunakan inline SQL sebagai anti-pola. Namun apa yang saya anggap sebagai anti-pola adalah setiap programmer melakukan hal mereka sendiri. Anda harus memutuskan sebagai tim berdasarkan standar umum. Jika semua orang menggunakan LINQ, maka Anda menggunakan LINQ, jika semua orang menggunakan tampilan dan prosedur tersimpan maka Anda melakukannya.
Selalu tetap berpikiran terbuka dan jangan jatuh cinta pada dogma. Jika toko Anda adalah toko "LINQ", Anda menggunakannya. Kecuali untuk satu tempat di mana LINQ benar-benar tidak berfungsi. (Tapi Anda seharusnya tidak 99,9% dari waktu.)
Jadi yang akan saya lakukan adalah meneliti kode di basis kode dan memeriksa bagaimana rekan kerja Anda.
sumber
Kode tersebut terlihat dari lapisan yang berinteraksi dengan database yang berada di antara basis data dan seluruh kode. Jika benar, ini bukan anti-pola.
Metode ini ADALAH bagian dari lapisan, bahkan jika OP berpikir berbeda (akses database biasa, tidak ada pencampuran dengan yang lain). Mungkin saja ditempatkan dengan buruk di dalam kode. Metode ini milik kelas yang terpisah, "lapisan antarmuka basis data". Ini akan menjadi anti-pola untuk menempatkannya di dalam kelas biasa di samping metode yang mengimplementasikan kegiatan non-database.
Anti-pola akan memanggil SQL dari beberapa tempat kode acak lainnya. Anda perlu mendefinisikan lapisan antara database dan sisa kode, tetapi bukan berarti Anda harus benar-benar menggunakan beberapa alat populer yang dapat membantu Anda di sana.
sumber
Menurut pendapat saya, tidak ada bukan pola anti tetapi Anda akan menemukan diri Anda berurusan dengan spasi pemformatan string, terutama untuk permintaan besar yang tidak dapat ditampung dalam satu baris.
kelebihan lainnya adalah semakin sulit ketika berhadapan dengan permintaan dinamis yang harus dibangun sesuai dengan kondisi tertentu.
Saya sarankan menggunakan pembuat kueri sql
sumber
Bagi banyak organisasi modern dengan jaringan pipa penyebaran cepat di mana perubahan kode dapat dikompilasi, diuji dan didorong untuk diproduksi dalam hitungan menit, sangat masuk akal untuk menanamkan pernyataan SQL ke dalam kode aplikasi. Ini belum tentu anti-pola tergantung pada bagaimana Anda melakukannya.
Kasus yang valid untuk menggunakan prosedur tersimpan hari ini adalah di organisasi di mana ada banyak proses di sekitar penyebaran produksi yang dapat melibatkan minggu siklus QA dll. Dalam skenario ini tim DBA dapat menyelesaikan masalah kinerja yang muncul hanya setelah penyebaran produksi awal dengan mengoptimalkan pertanyaan dalam prosedur tersimpan.
Kecuali Anda berada dalam situasi ini, saya sarankan Anda menanamkan SQL Anda ke dalam kode aplikasi Anda. Baca jawaban lain di utas ini untuk saran tentang cara terbaik untuk melakukannya.
Teks asli di bawah ini untuk konteks
Keuntungan utama dari prosedur tersimpan adalah Anda dapat mengoptimalkan kinerja basis data tanpa mengkompilasi ulang dan mempekerjakan kembali aplikasi Anda.
Dalam banyak organisasi kode hanya dapat didorong ke produksi setelah siklus QA dll yang dapat memakan waktu berhari-hari atau berminggu-minggu. Jika sistem Anda mengembangkan masalah kinerja basis data karena perubahan pola penggunaan atau peningkatan ukuran tabel dll, maka akan sangat sulit untuk melacak masalah dengan kueri yang dikodekan secara keras, sedangkan basis data akan memiliki alat / laporan dll yang akan mengidentifikasi masalah prosedur tersimpan . Dengan prosedur tersimpan, solusi dapat diuji / dijadikan patokan dalam produksi dan masalah ini dapat diperbaiki dengan cepat tanpa harus mendorong versi baru perangkat lunak aplikasi.
Jika masalah ini tidak penting dalam sistem Anda maka itu adalah keputusan yang benar-benar valid untuk pernyataan kode SQL yang sulit ke dalam aplikasi.
sumber