Apakah dianggap sebagai pola anti untuk menulis SQL dalam kode sumber?

87

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:

  1. Gunakan LINQ
    atau
  2. 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?

w0051977
sumber
31
"Gunakan Linq" dan "Gunakan prosedur tersimpan" bukan alasan; itu hanya saran. Tunggu dua minggu, dan tanyakan alasannya.
Robert Harvey
47
Jaringan Stack Exchange menggunakan micro-ORM yang disebut Dapper. Saya pikir masuk akal untuk mengatakan bahwa sebagian besar kode Dapper adalah "SQL hardcoded" (kurang lebih). Jadi jika ini adalah praktik buruk, maka itu adalah praktik buruk yang diadopsi oleh salah satu aplikasi web paling terkemuka di planet ini.
Robert Harvey
16
Untuk menjawab pertanyaan Anda tentang repositori, SQL hard-code masih berupa SQL hard-code di mana pun Anda menyimpannya. Perbedaannya adalah repositori memberi Anda tempat untuk merangkum SQL hard-coded. Ini adalah lapisan abstraksi yang menyembunyikan detail SQL dari sisa program.
Robert Harvey
26
Tidak, SQL dalam kode bukanlah anti-pola. Tapi itu banyak sekali kode pelat ketel untuk kueri SQL sederhana.
GrandmasterB
45
Ada perbedaan antara 'dalam kode sumber' dan 'tersebar di seluruh kode sumber'
tofro

Jawaban:

112

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 SQLCustomerRepositorytetapi tidak dalam a MongoCustomerRepository). 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.

marstato
sumber
80
Gagasan bahwa "kita dapat mengubah teknologi ketekunan" tidak realistis dan tidak perlu dalam sebagian besar proyek dunia nyata. SQL / DB relasional adalah binatang yang sama sekali berbeda dari DB NoSQL seperti MongoDB. Lihat artikel rinci tentang ini. Paling-paling, sebuah proyek yang mulai menggunakan NoSQL pada akhirnya akan menyadari kesalahan mereka dan kemudian beralih ke RDBMS. Dalam pengalaman saya, mengizinkan penggunaan langsung Bahasa Query berorientasi objek (seperti JPA-QL) dari kode bisnis memberikan hasil terbaik.
Rogério
6
Bagaimana jika ada sedikit peluang lapisan kegigihan diubah? Bagaimana jika tidak ada pemetaan satu-ke-satu saat mengubah lapisan persistensi? Apa keuntungan dari tingkat abstraksi ekstra?
mundur
19
@ Rogério Migrasi dari toko NoSQL ke RDBMS, atau sebaliknya, seperti yang Anda katakan mungkin tidak realistis (dengan asumsi pilihan teknologi tepat untuk memulai). Namun, saya telah terlibat dalam sejumlah proyek dunia nyata di mana kami bermigrasi dari satu RDBMS ke yang lain; dalam skenario itu, lapisan kegigihan yang dienkapsulasi jelas merupakan keuntungan.
David
6
"Gagasan bahwa" kita dapat mengubah teknologi kegigihan "tidak realistis dan tidak perlu di sebagian besar proyek dunia nyata." Perusahaan saya sebelumnya menulis kode di sepanjang asumsi itu. Kami harus memperbaiki seluruh basis kode untuk mendukung tidak hanya satu, tetapi tiga sistem penyimpanan / kueri yang sama sekali berbeda dan sedang mempertimbangkan yang ketiga dan keempat. Lebih buruk lagi, bahkan ketika kita hanya memiliki satu basis data, kurangnya konsolidasi menyebabkan semua jenis kode dosa.
NPSF3000
3
@ Rogério Anda tahu "sebagian besar proyek dunia nyata"? Di perusahaan saya, sebagian besar aplikasi dapat bekerja dengan salah satu dari banyak DBMS umum, dan ini sangat berguna, karena sebagian besar klien kami memang memiliki persyaratan nonfungsional mengenai hal itu.
BartoszKP
55

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.

Doc Brown
sumber
1
Saya telah mengedit pertanyaan. Tidak yakin apakah itu menerangi.
w0051977
18
@ w0051977: tautan yang Anda poskan tidak memberi tahu kami apa pun tentang aplikasi Anda , bukan? Tampaknya Anda sedang mencari beberapa aturan sederhana, braindead di mana menempatkan SQL atau tidak yang cocok untuk setiap aplikasi. Tidak ada. Ini adalah keputusan desain yang harus Anda buat tentang aplikasi individual Anda (mungkin bersama-sama dengan tim Anda).
Doc Brown
7
+1. Secara khusus saya akan mencatat bahwa tidak ada perbedaan nyata antara SQL dalam suatu metode, dan SQL dalam prosedur tersimpan, dalam hal seberapa "sulit dikodekan" sesuatu, atau bagaimana dapat digunakan kembali, dipelihara, dll. Abstraksi apa pun yang dapat Anda lakukan dengan Prosedur dapat dilakukan dengan suatu metode. Tentu saja prosedur bisa bermanfaat, tetapi aturan hafalan "kita tidak bisa memiliki SQL dalam metode, jadi mari kita semua dalam prosedur" mungkin hanya akan menghasilkan banyak kesalahan dengan sedikit manfaat.
1
@ user82096 Saya akan mengatakan secara umum menempatkan kode akses db di SP telah merugikan di hampir setiap proyek yang saya lihat. (MS stack) Selain degradasi kinerja aktual (cache rencana eksekusi yang kaku), pemeliharaan sistem menjadi lebih sulit dengan memiliki logika yang terpecah-pecah, dan SP dikelola oleh sekelompok orang yang berbeda dari pengembang logika aplikasi. Terutama pada Azure di mana perubahan kode antara Deployment Slots seperti detik kerja, tetapi migrasi skema non code-first / db-first antara slot adalah sedikit sakit kepala operasional.
Sentinel
33

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:

Di Hibernate, saya mengulangi 250.000 catatan yang memeriksa nilai beberapa properti dan memperbarui objek yang cocok dengan kondisi tertentu. Ini berjalan agak lambat, apa yang bisa saya lakukan untuk mempercepatnya?

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.

mcottle
sumber
5
Saya tidak menyatakan "vendor lock-in" adalah hal yang buruk. Saya menyatakan itu datang dengan trade-off. Di pasar saat ini dengan db sebagai xaaS kontrak lama dan lisensi untuk menjalankan db selfhosted akan semakin langka. Lebih mudah hari ini untuk mengubah db dari vendor A ke B dibandingkan dengan 10 tahun yang lalu. Jika Anda membaca komentar, saya tidak suka mengambil keuntungan dari semua fitur penyimpanan data. Jadi Sangat mudah untuk memasukkan beberapa detail vendor tertentu ke dalam sesuatu (aplikasi) yang dimaksudkan sebagai vendor agnostik. Kami berusaha untuk mengikuti SOLiD hanya untuk akhirnya mengunci kode ke penyimpanan data tunggal. Bukan masalah besar
Laiv
2
Ini jawaban yang bagus. Seringkali pendekatan yang tepat adalah yang mengarah pada situasi yang paling buruk jika kode terburuk ditulis. Kode ORM terburuk yang mungkin mungkin jauh lebih buruk daripada SQL tertanam terburuk.
jwg
@Laiv poin bagus PaaS adalah sedikit pengubah permainan - saya harus lebih memikirkan implikasinya.
mcottle
3
@ jwg Saya akan cenderung mengatakan bahwa di atas rata-rata kode ORM lebih buruk daripada di bawah rata-rata tertanam SQL :)
mcottle
@ macottle Dengan asumsi bahwa rata-rata tertanam SQL ditulis oleh ppl di atas rata-rata orang yang menulis ORM. Yang saya sangat meragukannya. Banyak pengembang di luar sana tidak dapat menulis JOIN kiri tanpa memeriksa SO dulu.
Laiv
14

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.

Clean Code oleh Robert C. Martin, pg.  288 (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:

  • Logika basis data sulit ditemukan. Apa yang Anda cari untuk menemukan semua pernyataan SQL Anda? String dengan "SELECT", "UPDATE", "MERGE", dll?
  • Penggunaan refactoring dari SQL yang sama atau serupa menjadi sulit.
  • Menambahkan dukungan untuk database lain sulit. Bagaimana seseorang mencapai ini? Tambahkan if..then pernyataan untuk setiap database dan simpan semua pertanyaan sebagai string dalam metode ini?
  • Pengembang membaca pernyataan dalam bahasa lain dan menjadi terganggu oleh pergeseran fokus dari tujuan metode ke rincian implementasi metode (bagaimana dan dari mana data diambil).
  • Sementara one-liners mungkin tidak terlalu banyak masalah, string SQL inline mulai berantakan ketika pernyataan menjadi lebih kompleks. Apa yang Anda lakukan dengan pernyataan garis 113? Masukkan semua 113 baris dalam metode Anda?
  • Bagaimana pengembang efisien memindahkan pertanyaan bolak-balik antara editor SQL mereka (SSMS, SQL Developer, dll.) Dan kode sumbernya? @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"\
  • Lekukan karakter yang digunakan untuk menyelaraskan SQL dengan kode aplikasi di sekitarnya ditransmisikan melalui jaringan dengan setiap eksekusi. Ini mungkin tidak signifikan untuk aplikasi skala kecil, tetapi dapat bertambah seiring dengan meningkatnya penggunaan perangkat lunak.

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 ?:

using(DbConnection connection = Database.SystemConnection()) {
    var eyesoreSql = @"
    SELECT
        Viewable.ViewId,
        Viewable.HelpText,
        PageSize.Width,
        PageSize.Height,
        Layout.CSSClass,
        PaginationType.GroupingText
    FROM Viewable
    LEFT JOIN PageSize
        ON PageSize.Id = Viewable.PageSizeId
    LEFT JOIN Layout
        ON Layout.Id = Viewable.LayoutId
    LEFT JOIN Theme
        ON Theme.Id = Viewable.ThemeId
    LEFT JOIN PaginationType
        ON PaginationType.Id = Viewable.PaginationTypeId
    LEFT JOIN PaginationMenu
        ON PaginationMenu.Id = Viewable.PaginationMenuId
    WHERE Viewable.Id = @Id
    ";
    var results = connection.Query<int>(eyesoreSql, new { Id });
}

Menjadi

using(DbConnection connection = Database.SystemConnection()) {
    var results = connection.Query<int>(sql.GetViewable, new { Id });
}

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 :

SQL dalam sumber daya

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:

  1. Kode basis data mudah ditemukan karena sudah terpusat. Dalam proyek yang lebih besar, kelompok seperti-SQL ke dalam file terpisah, mungkin di bawah folder bernama SQL.
  2. Dukungan untuk database kedua, ketiga, dll. Lebih mudah. Buat antarmuka (atau abstraksi bahasa lain) yang mengembalikan pernyataan unik setiap basis data. Implementasi untuk setiap database menjadi sedikit lebih dari pernyataan yang mirip dengan: 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.
  3. Refactoring sederhana - gunakan kembali sumber daya yang sama. Anda bahkan dapat menggunakan entri sumber daya yang sama untuk sistem DBMS yang berbeda sebagian besar waktu dengan beberapa pernyataan format. Saya sering melakukan ini.
  4. Penggunaan bahasa sekunder dapat menggunakan nama-nama deskriptif misalnya sql.GetOrdersForAccountdaripada lebih tumpulSELECT ... FROM ... WHERE...
  5. Pernyataan SQL dipanggil dengan satu baris terlepas dari ukuran dan kompleksitasnya.
  6. SQL dapat disalin dan ditempel di antara alat basis data seperti SSMS dan SQL Developer tanpa modifikasi atau penyalinan yang cermat. Tidak ada tanda kutip. Tidak ada garis miring terbalik. Khusus untuk editor sumber daya Visual Studio, satu klik menyoroti pernyataan SQL. CTRL + C lalu tempelkan ke editor SQL.

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.

Charles Burns
sumber
13
Saya pikir ini terlalu banyak berfokus pada kritik buruk memiliki SQL dalam kode sumber. Memiliki dua bahasa berbeda dalam file yang sama belum tentu mengerikan. Itu tergantung pada banyak hal seperti bagaimana mereka berhubungan dan bagaimana masing-masing disajikan.
jwg
9
"Menggabungkan bahasa yang sama sekali berbeda dengan sintaks yang berbeda dalam file yang sama" Ini adalah argumen yang mengerikan. Ini juga berlaku untuk mesin tampilan Razor, dan HTML, CSS dan Javascript. Cintai novel grafis Anda!
Ian Newson
4
Ini hanya mendorong kompleksitas di tempat lain. Ya, kode asli Anda lebih bersih, dengan mengorbankan menambahkan tipuan yang sekarang harus dinavigasi oleh pengembang untuk tujuan pemeliharaan. Alasan sebenarnya Anda akan melakukan ini adalah jika setiap pernyataan SQL digunakan di banyak tempat dalam kode. Dengan cara itu, itu benar-benar tidak berbeda dari refactoring biasa lainnya ("Metode Ekstrak").
Robert Harvey
3
Untuk lebih jelas, ini bukan jawaban untuk pertanyaan "apa yang harus saya lakukan dengan string SQL saya," sebanyak itu adalah jawaban untuk pertanyaan "apa yang saya lakukan dengan kumpulan string yang cukup kompleks," sebuah pertanyaan yang jawaban Anda dengan fasih menjawab.
Robert Harvey
2
@RobertHarvey: Saya yakin pengalaman kami berbeda, tetapi dalam pengalaman saya sendiri saya telah menemukan abstraksi yang dimaksud sebagai kemenangan dalam banyak kasus. Saya pasti akan memperbaiki pengorbanan abstraksi saya karena saya telah melakukan naik turun selama bertahun-tahun, dan suatu hari nanti dapat mengembalikan SQL ke dalam kode. YMMV. :) Saya pikir microservices bisa menjadi besar, dan mereka juga umumnya memisahkan rincian SQL Anda (jika SQL digunakan sama sekali) dari kode aplikasi inti. Saya kurang menganjurkan "gunakan metode spesifik saya: sumber daya" dan lebih banyak menganjurkan "Umumnya tidak mencampur bahasa minyak dan air."
Charles Burns
13

Tergantung. Ada sejumlah pendekatan berbeda yang dapat bekerja:

  1. Modularisasi SQL, dan pisahkan ke dalam sekumpulan kelas, fungsi, atau unit abstraksi apa pun yang digunakan paradigma Anda, kemudian panggil ke dalamnya dengan logika aplikasi.
  2. Pindahkan semua SQL yang kompleks ke tampilan, dan kemudian hanya lakukan SQL yang sangat sederhana dalam logika aplikasi, sehingga Anda tidak perlu memodulasi apa pun.
  3. Gunakan perpustakaan pemetaan objek-relasional.
  4. YAGNI, cukup tulis SQL langsung di logika aplikasi.

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 (yaituCREATE 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 seperti INSERT, UPDATE, atau DELETE, 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.

Kevin
sumber
2 seperti yang ditulis pada dasarnya mengasumsikan basis data hanya baca. Prosedur tersimpan dulu tidak jarang untuk permintaan yang memodifikasi.
jpmc26
@ jpmc26: Saya sampul menulis dalam tanda kurung ... apakah Anda memiliki rekomendasi khusus untuk meningkatkan jawaban ini?
Kevin
Hm Permintaan maaf untuk komentar sebelum menyelesaikan jawaban dan kemudian terganggu. Tetapi tampilan yang dapat diperbarui membuatnya agak sulit untuk melacak di mana tabel sedang diperbarui. Membatasi pembaruan secara langsung di atas tabel, terlepas dari mekanisme, memang memiliki kelebihan dalam hal memahami logika kode. Jika Anda membatasi logika ke DB, maka, Anda tidak bisa memaksakan itu tanpa prosedur yang tersimpan. Mereka juga memiliki keunggulan memungkinkan beberapa operasi dengan satu panggilan. Intinya: Saya tidak berpikir Anda harus begitu keras pada mereka.
jpmc26
@ jpmc26: Itu adil.
Kevin
8

Apakah dianggap sebagai anti-pola untuk menulis SQL dalam kode 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.

berasumsi bahwa yang dia maksudkan; antara:

1) Gunakan LINQ

atau

2) Gunakan prosedur tersimpan untuk SQL

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.

Keuntungan dari prosedur tersimpan menurut saya adalah bahwa SQL Developers dapat terlibat dengan proses pengembangan (menulis prosedur tersimpan dll)

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.

Sunting: Tautan berikut berbicara tentang pernyataan SQL yang dikode-keras:  https://docs.microsoft.com/en-us/sql/odbc/reference/develop-app/hard-coded-sql-statements . Apakah ada manfaat mempersiapkan pernyataan SQL?

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.

Laiv
sumber
1
Terima kasih. +1 untuk "Pernyataan SQL Hardcoding dapat mengarahkan Anda untuk menghubungkan erat aplikasi Anda ke engine db.". Saya mengembara jika ia merujuk ke SQL Server daripada SQL yaitu menggunakan SQLConnection daripada dbConnection; SQLCommand daripada dbCommand dan SQLDataReader daripada dbDataReader.
w0051977
Tidak. Saya merujuk pada penggunaan ekspresi yang tidak sesuai dengan ANSI. Sebagai contoh: select GETDATE(), ....GETDATE () adalah fungsi tanggal SqlServer. Di mesin lain, fungsinya memiliki nama berbeda, ekspresi berbeda, ...
Laiv
14
"Vendor lock-in" ... Seberapa seringkah orang / perusahaan benar - benar memigrasi basis data produk yang ada ke RDBMS lain? Bahkan dalam proyek yang menggunakan ORM eksklusif, saya tidak pernah melihat itu terjadi: biasanya perangkat lunak ditulis ulang dari awal juga, karena kebutuhan telah berubah di antaranya. Oleh karena itu, memikirkan ini sepertinya seperti "optimasi prematur" bagi saya. Ya, ini sangat subjektif.
Olivier Grégoire
1
Saya tidak peduli seberapa sering terjadi. Saya peduli Itu mungkin terjadi. Dalam proyek greenfield, biaya implementasi DAL yang disarikan dari db hampir 0. Migrasi yang mungkin tidak. Argumen menentang ORM cukup lemah. ORM tidak seperti 15 tahun yang lalu ketika Hibernate cukup hijau. Apa yang saya lihat adalah banyak konfigurasi "secara default" dan desain model data yang lebih buruk. Ini seperti banyak alat lainnya, banyak orang melakukan tutorial "memulai" dan mereka tidak peduli apa yang terjadi di bawah tenda. Alat ini bukan problema. Masalahnya adalah siapa yang tidak tahu bagaimana dan kapan menggunakannya.
Laiv
Di sisi lain, vendor terkunci tidak selalu buruk. Jika saya ditanya saya akan mengatakan saya tidak suka . Namun, saya sudah dikunci ke Spring, Tomcat atau JBoss atau Websphere (masih lebih buruk). Yang bisa saya hindari, saya lakukan. Aku tidak bisa hidup dengan itu. Ini masalah preferensi.
Laiv
3

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.

Sava B.
sumber
Mengizinkan DBA mengubah SQL Anda tanpa memperbarui aplikasi secara efektif membagi aplikasi Anda menjadi dua entitas yang dikembangkan secara terpisah, yang digunakan secara terpisah. Anda sekarang perlu mengelola kontrak antarmuka di antara mereka, menyinkronkan rilis perubahan yang saling tergantung, dll. Ini mungkin hal yang baik atau buruk, tetapi lebih dari sekadar "meletakkan semua SQL Anda di satu tempat", itu jauh -mencapai keputusan arsitektur.
IMSoP
2

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

    string query = 
    @"SELECT foo, bar
      FROM table
      WHERE id = @tn";
tebing
sumber
7
Masalah yang paling mencolok dengan ini adalah masalah dari mana nilai itu berasal. Apakah Anda menggabungkan nilai itu ke dalam string? Jika demikian, dari mana asalnya? Bagaimana cara menggosok untuk mengurangi serangan injeksi SQL? Mengapa contoh ini tidak menampilkan kueri parameterisasi?
Craig
Saya hanya bermaksud menunjukkan format. Maaf, saya lupa membuat parameter. Sekarang diperbaiki setelah merujuk ke msdn.microsoft.com/library/bb738521(v=vs.100).aspx
rleir
+1 untuk pentingnya pemformatan, meskipun saya berpendapat bahwa string SQL adalah bau kode terlepas dari pemformatan.
Charles Burns
1
Apakah Anda bersikeras menggunakan ORM? Ketika ORM tidak digunakan, untuk proyek yang lebih kecil, saya menggunakan kelas 'shim' yang berisi SQL tertanam.
rleir
String SQL jelas bukan bau kode. Tanpa ORM, sebagai manajer dan arsitek, saya akan mendorong mereka menggunakan SP untuk alasan pemeliharaan dan terkadang kinerja.
Sentinel
1

Saya tidak bisa memberi tahu Anda apa yang dimaksud rekan kerja Anda. Tapi saya bisa menjawab ini:

Apakah ada manfaat mempersiapkan pernyataan SQL?

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:

List<UUID> ids = select(person.id).from(person).fetch();

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 personvariabel 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 ...

meriton - mogok
sumber
Agar lebih jelas: Menggunakan pernyataan yang disiapkan tidak mencegah injeksi SQL. Menggunakan pernyataan yang disiapkan dengan variabel terikat tidak. Dimungkinkan untuk menggunakan pernyataan yang disiapkan yang dibangun dari data yang tidak dipercaya.
Andy Lester
1

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.

Pieter B
sumber
+1 Poin bagus. Supportabilitas lebih penting daripada kebanyakan pertimbangan lain jadi jangan terlalu pintar :) Yang mengatakan, jika Anda seorang toko ORM jangan lupa bahwa ada contoh di mana ORM bukan jawabannya dan Anda perlu menulis SQL langsung. Jangan optimalkan secara prematur tetapi akan ada waktu dalam aplikasi non-sepele ketika Anda harus turun rute ini.
mcottle
0

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.

h22
sumber
0

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.

var query = "select * from accounts";

if(users.IsInRole('admin'))
{
   query += " join secret_balances";
}

Saya sarankan menggunakan pembuat kueri sql

amd
sumber
Mungkin Anda hanya menggunakan singkatan tapi itu ide yang sangat buruk untuk secara buta menggunakan "SELECT *" karena Anda akan membawa kembali bidang yang tidak Anda butuhkan (bandwidth !!) Juga meskipun saya tidak memiliki masalah dengan klausa kondisional Admin klausa itu mengarah ke lereng yang sangat licin ke klausa "WHERE" bersyarat dan itulah jalan yang mengarah langsung ke neraka kinerja.
mcottle
0

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.

bikeman868
sumber
Salah ...........
Sentinel
Apakah menurut Anda komentar Anda bermanfaat bagi siapa pun?
bikeman868
Ini benar-benar salah. Katakanlah kita memiliki proyek Web API2 dengan EF sebagai akses data dan Azure Sql sebagai penyimpanan. Tidak, mari kita singkirkan EF dan gunakan SQL buatan tangan. Skema db disimpan dalam proyek SSDT SQL Server. Migrasi skema db melibatkan memastikan basis kode disinkronkan ke skema db dan sepenuhnya diuji, sebelum mendorong perubahan ke tes db dalam perubahan kode Azure.A melibatkan mendorong keluar ke slot penyebaran Layanan App, yang membutuhkan waktu 2 detik. Ditambah SQL buatan tangan memiliki kinerja plus lebih dari prosedur yang tersimpan, secara umum, meskipun 'kebijaksanaan' sebaliknya.
Sentinel
Dalam kasus Anda, penerapan mungkin memerlukan waktu beberapa detik, tetapi ini tidak berlaku untuk banyak orang. Saya tidak mengatakan bahwa prosedur tersimpan lebih baik, hanya saja mereka memiliki beberapa keuntungan dalam beberapa keadaan. Pernyataan terakhir saya adalah bahwa jika keadaan ini tidak berlaku maka menempatkan SQL dalam aplikasi sangat valid. Bagaimana ini bertentangan dengan apa yang Anda katakan?
bikeman868
Prosedur tersimpan adalah kerajinan tangan SQL ???
bikeman868