Kaynak kodda SQL yazmak için anti-pattern olarak mı kabul edilir?


87

SQL'i aşağıdaki gibi bir uygulamaya kodlamak için anti-pattern olarak kabul edilir:

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

Normalde depo katmanı vb. Olurdu, ancak basitlik için yukarıdaki koda dahil etmedim.

Geçenlerde SQL'in kaynak kodunda yazıldığından şikayet eden bir meslektaşımdan geri bildirim aldım. Nedenini sorma şansım olmadı ve şimdi iki hafta uzakta (belki daha fazla). Onun da demek istediğini varsayıyorum:

  1. LINQ kullanın
    veya
  2. SQL için saklı yordamları kullan

Doğrumuyum? Kaynak kodda SQL yazmak için anti-pattern olarak mı kabul edilir? Bu proje üzerinde çalışan küçük bir ekibiz. Saklı yordamların yararı, SQL Geliştiricilerin geliştirme işlemine (saklı yordamları yazma vb.) Dahil olmaları olduğunu düşünüyorum.

Düzenleme Aşağıdaki bağlantı kodlanmış SQL ifadeleri hakkında konuşur: https://docs.microsoft.com/en-us/sql/odbc/reference/develop-app/hard-coded-sql-statements . SQL deyimi hazırlamanın bir faydası var mı?


31
"Linq Kullan" ve "Saklı yordamları kullan" neden değildir; onlar sadece öneridir. İki hafta bekle ve nedenlerden sor.
Robert Harvey,

47
Stack Exchange ağı, Dapper adlı bir mikro-ORM kullanır. Dapper kodunun büyük çoğunluğunun "kodlanmış SQL" (az ya da çok) olduğunu söylemenin makul olduğunu düşünüyorum. Bu yüzden kötü bir uygulama ise, o zaman dünyadaki en önde gelen web uygulamalarından biri tarafından benimsenen kötü bir uygulama.
Robert Harvey,

16
Depolar hakkındaki sorunuza cevap vermek için, sabit kodlanmış SQL, nereye koyduğunuz önemli değil, hala zor kodlanmış SQL'dir. Aradaki fark, havuzun size sabit kodlanmış SQL'i kapsama için bir yer sağlamasıdır . SQL'in ayrıntılarını programın geri kalanından gizleyen bir soyutlama katmanıdır.
Robert Harvey,

26
Hayır, kod içindeki SQL bir anti-pattern değildir. Fakat basit bir SQL sorgusu için çok fazla kazan plakası kodu var.
GrandmasterB

45
'Kaynak kodunda' ile 'kaynak koduna yayılmış' arasında bir fark var
tofro

Yanıtlar:


112

Basitlik için çok önemli olan kısmı hariç tuttunuz. Depo kalıcılık için soyutlama katmanıdır. Biz böylece biz kendi katmanına kalıcılığını ayırmak değiştirmek biz gerektiğinde daha kolay kalıcılık teknolojisini. Dolayısıyla, kalıcılık katmanı dışında SQL'e sahip olmak ayrı bir kalıcılık katmanına sahip olma çabasını tamamen ortadan kaldırır.

Sonuç olarak: SQL, bir SQL teknolojisine özgü kalıcılık katmanı içinde iyidir (örneğin, SQL, a'da SQLCustomerRepositorydeğil, tamamdır MongoCustomerRepository). Kalıcılık katmanının dışında, SQL soyutlamanızı kırar ve bu nedenle (benim tarafımdan) çok kötü bir uygulama olarak kabul edilir .

LINQ veya JPQL gibi araçlara gelince: Bunlar yalnızca SQL'in lezzetlerini soyutlayabilir. LINQ-Code veya JPQL sorgularının bir havuzun dışında olması, ham SQL'in yapacağı kadar kalıcı bir soyutlamayı bozar.


Ayrı bir kalıcılık katmanının bir diğer büyük avantajı, bir DB sunucusu kurmanıza gerek kalmadan iş mantığı kodunuzu en içten çekmenize izin vermesidir.

Dilinizin desteklediği tüm platformlarda düşük bellek profilli, hızlı birim testleri ve tekrarlanabilir sonuçlar elde edersiniz.

Bir MVC + Hizmet mimarisinde bu, havuz örneğini alay etmek, bellekte sahte bir veri oluşturmak ve havuzun belirli bir alıcı çağrıldığında bu sahte verileri döndürmesi gerektiğini tanımlamak için basit bir iştir. Daha sonra en iç başına test verilerini tanımlayabilir ve daha sonra DB'yi temizleme konusunda endişelenmeyin.

DB'ye yazmaların test edilmesi basittir: Kalıcılık katmanındaki ilgili güncelleme yöntemlerinin çağrıldığını doğrulayın ve varlıkların bu olduğunda doğru durumda olduklarını iddia edin.


80
“Kalıcılık teknolojisini değiştirebiliriz” düşüncesi, gerçek dünyadaki projelerin büyük çoğunluğunda gerçekçi ve gereksizdir. Bir SQL / ilişkisel DB, MongoDB gibi NoSQL DB'lerden tamamen farklı bir canavardır. Bununla ilgili bu ayrıntılı makaleye bakın . En fazla NoSQL kullanmaya başlayan bir proje sonunda hatalarını anlar ve ardından bir RDBMS'ye geçer. Tecrübelerime göre, doğrudan kullanımın nesne yönelimli bir Sorgu Dili (JPA-QL gibi) iş kodundan kullanılmasına izin vermesi en iyi sonuçları sağlar.
Rogério

6
Kalıcılık katmanının değiştirilme şansı çok düşükse ne olur? Kalıcılık katmanını değiştirirken bire bir eşleme yoksa? Ekstra soyutlama seviyesinin avantajı nedir?
plise

19
@ Rogério Bir NoSQL mağazasından bir RDBMS'ye geçmek veya tam tersi, muhtemelen gerçekçi olmadığını söylediğiniz gibi (teknoloji seçiminin başlaması uygun olduğu varsayılarak). Ancak, bir RDBMS'den diğerine geçirdiğimiz birçok gerçek dünya projesinde yer aldım; Bu senaryoda, kapsüllenmiş bir kalıcılık katmanı kesinlikle bir avantajdır.
David,

6
“Kalıcılık teknolojisini değiştirebiliriz” düşüncesi, gerçek dünyadaki projelerin büyük çoğunluğunda gerçekçi ve gereksizdir. ”Şirketim daha önce bu varsayım boyunca kod yazmıştı. Bir tane değil üç farklı depolama / sorgulama sistemini desteklemek için tüm kod tabanını yeniden yapılandırmamız gerekti ve üçüncü ve dördüncüleri düşünüyoruz. Daha da kötüsü, sadece bir veritabanımız olsa bile, konsolidasyon eksikliği her türlü kod günahına yol açtı.
NPSF3000,

3
@ Rogério "Gerçek dünyadaki projelerin büyük çoğunluğunu" biliyor musunuz? Şirketimde çoğu uygulama birçok yaygın DBMS'den biriyle çalışabilir ve çoğu müşterimiz bununla ilgili işlevsel olmayan gereksinimlere sahip olduğu için bu çok kullanışlıdır.
BartoszKP

55

Günümüzde çoğu standart işletme uygulaması farklı sorumluluklara sahip farklı katmanlar kullanmaktadır. Ancak, hangi katmanları için kullanmak sizin uygulaması ve hangi katman size ve ekibinize kadar olan sorumluluk vardır. SQL'i bize gösterdiğiniz işleve doğrudan yerleştirmenin doğru veya yanlış olup olmadığına karar vermeden önce, bilmeniz gerekenler

  • uygulamanızda hangi katmanın sorumluluğu var

  • Yukarıdaki fonksiyon hangi katmandan

Buna "tek beden uyan herkese" bir çözüm yoktur. Bazı uygulamalarda, tasarımcılar bir ORM çerçevesi kullanmayı tercih eder ve çerçevenin bütün SQL'i oluşturmasını sağlar. Bazı uygulamalarda, tasarımcılar bu tür SQL'i yalnızca saklı prosedürlerde saklamayı tercih eder. Bazı uygulamalar için, SQL'in yaşadığı elle yazılmış bir kalıcılık (veya depo) katmanı vardır ve diğer uygulamalar için, belirli koşullar altında SQL'i kesin bir şekilde kalıcı kılmaktan kaynaklanan istisnaları tanımlamak uygundur.

Yani düşünmek için gerekenleri: Eğer hangi katmanları istiyorum veya ihtiyaç belirli uygulamada ve nasıl yok sen sorumluluklar ister misin? "Normalde bir depo katmanına sahip olurum" yazmıştınız , ancak bu katmanın içinde olmasını istediğiniz tam sorumluluklar nelerdir ve başka bir yere ne gibi sorumluluklar koymak istersiniz? Önce bunu cevaplayın, sonra sorunuzu kendiniz cevaplayabilirsiniz.


1
Soruyu değiştirdim. Işık tuttuğu kesin değil.
w0051977

18
@ w0051977: Yayınladığınız bağlantı bize hakkında hiçbir şey söylemez sizin Doğru uygulama,? Her uygulama için uygun olan ya da SQL'in yerleştirileceği bazı basit, braindead kurallarını aradığınız görülüyor. Hiçbiri yok. Bu tasarım kararı olduğunu sen hakkında yapmak zorunda sizin (ekibinizle muhtemelen beraber) bireysel başvuru.
Doktor Brown,

7
+1. Özellikle, bir yöntemde SQL ile saklanmış yordamda SQL arasında bir şeyin ne kadar "zor kodlanmış" olduğu veya ne kadar yeniden kullanılabilir, bakım yapılabilir, vb. Gibi gerçek bir fark olmadığını unutmayın. işlem bir yöntemle yapılabilir. Elbette prosedürler faydalı olabilir, ancak bir ezber kuralı "yöntemlerde SQL'e sahip olamayız, bu yüzden hepsini prosedürlere koyalım" muhtemelen büyük olasılıkla çok az fayda sağlayacak bir sürü ham petrol üretecektir.

1
@ user82096 Genel olarak, SP'lere db erişim kodunu koymaktan bahsettiğim hemen her projede zararlı olduğunu söyleyebilirim. (MS yığını) Gerçek performans bozulmalarının yanı sıra (katı uygulama planı önbellekleri), sistemin bakımı, mantıksal bölünmüş durumdayken ve SP'ler, uygulama mantığı geliştiricilerinden farklı bir grup insan tarafından bakımı zorlaştırılmıştır. Özellikle Dağıtım Yuvaları arasında kodun değiştiği Azure'da çalışma saniyeler gibi, ancak yuvalar arasında ilk kod olmayan / ilk önce şema göçü biraz operasyonel bir baş ağrısından kaynaklanıyor.
Sentinel

33

Marstato iyi bir cevap veriyor ama biraz daha yorum eklemek isterim.

Kaynaktaki SQL bir anti-pattern değildir, ancak sorunlara neden olabilir. SQL sorgularını her forma bırakılan bileşenlerin özelliklerine koymak zorunda kaldığınızı hatırlayabiliyorum. Bu, işleri gerçekten çok çirkin hale getirdi ve sorguları bulmak için çemberin içinden atlamak zorunda kaldı. Çalıştığım dillerin sınırları dahilinde, Veritabanı erişimini mümkün olduğunca merkezileştirmenin güçlü bir savunucusu oldum. Meslektaşınız bu karanlık günlere geri dönüş yapıyor olabilir.

Şimdi, yorumların bazıları otomatik olarak kötü bir şeymiş gibi satıcı kilitlenmesi hakkında konuşuyor. Değil. Her yıl Oracle kullanmak için altı rakamlı bir onay işareti imzalarsam, söz konusu veritabanına erişen herhangi bir uygulamanın ekstra Oracle sözdizimini uygun şekilde kullanmasını istediğimi iddia edebilirsiniz.ama onun 'dolu. Parlak veri tabanım, veri tabanına zarar vermeyen SQL yazmanın "Oracle yolu" varken, kötü bir şekilde vanilya ANSI SQL yazan kodlayıcılar tarafından sakatlanırsa mutlu olmayacağım. Evet, veritabanlarını değiştirmek daha zor olacak ama 20 yıldan uzun bir süredir sadece büyük bir müşteri sitesinde yapıldığını gördüm ve bu vakalardan biri DB2 -> Oracle'dan taşınıyordu çünkü DB2'yi barındıran ana bilgisayar eskiydi ve kullanımdan kaldırılıyordu. . Evet, bu satıcı kilitlemesidir, ancak kurumsal müşteriler için, Oracle veya Microsoft SQL Server gibi pahalı bir yetenekli RDBMS için ödeme yapmak ve ardından bunu en yüksek ölçüde kullanmak arzu edilir. Konfor battaniyeniz olarak bir destek anlaşmanız var. Zengin saklı yordam uygulaması olan bir veritabanı için ödeme yapıyorsam,

Bu, bir sonraki noktaya yol açar, bir SQL Veritabanına erişen bir uygulama yazarsanız , diğer dilde olduğu gibi SQL'i de öğrenmek zorundasınız ve öğrenerek, sorgu optimizasyonunu da kastediyorum; Akıllıca parametrelendirilmiş bir sorgu kullandığınızda, SQL önbelleğini neredeyse aynı sorguların bir barajı ile temizleyen SQL oluşturma kodunu yazarsanız, size kızacağım.

Mazeret yok, Hazırda Bekleme duvarının arkasına saklanmak yok. Kötü kullanılan ORM'ler uygulamaların performansını gerçekten olumsuz etkileyebilir . Birkaç yıl önce Stack Overflow hakkında bir soru gördüğümü hatırlıyorum:

Hazırda Bekletme modunda, birkaç özelliğin değerlerini denetleyen ve belirli koşullarla eşleşen nesneleri güncelleyen 250.000 kayıt arasında yineleme yapıyorum. Biraz yavaş çalışıyor, hızlandırmak için ne yapabilirim?

"UPDATE table SET field1 = burada field2, Doğru ve Field3> 100" dür. 250.000 nesnenin oluşturulması ve elden çıkarılması sizin probleminiz olabilir ...

yani Kullanmak uygun olmadığında Hazırda Bekletme durumunu Yoksay. Veritabanını anlayın.

Bu nedenle, özet olarak, SQL'i koda gömmek kötü bir uygulama olabilir, ancak SQL'i gömmekten kaçınmaya çalışırken başarabileceğiniz çok daha kötü şeyler var.


5
"Satıcı kilitlenmesi" nin kötü bir şey olduğunu söylemedim. Değişim ile geldiğini belirttim. Günümüzde xaaS db olan pazarda bu tür eski sözleşmeler ve selfhosted db çalıştırmak için lisanslar giderek daha nadir olacak. Bugün db'yi A'dan B'ye değiştirmek 10 yıl öncesine göre çok daha kolay. Yorumları okuduysanız, veri deposunun herhangi bir özelliğinden yararlanmanın lehine değilim. Bu nedenle, belirli satıcı ayrıntılarını, satıcı agnostiği anlamına gelen bir uygulamaya (app) koymak kolaydır. SOLiD'i sadece sonuna kadar kodu tek bir veri deposuna kilitlemek için takip etmeye çalışıyoruz. Çok önemli bir şey değil
Laiv

2
Bu harika bir cevap. Genellikle doğru yaklaşım, mümkün olan en kötü kod yazıldığında en kötü duruma yol açan yaklaşımdır. Olası en kötü ORM kodu, olabilecek en kötü gömülü SQL'den çok daha kötü olabilir.
jwg

@Laiv iyi puanları PaaS bir oyun değiştiricinin bir parçası - sonuçları hakkında daha fazla düşünmek zorunda kalacağım.
mcottle,

3
@jwg Ortalamanın üzerinde ORM kodunun ortalama gömülü
SQL'den

@macottle Aşağıdaki ortalama gömülü SQL'nin, ORM yazan ortalamanın üstünde ppl tarafından yazıldığını varsayar. Şüphelendiğim şey çok fazla. Dışarıdaki çoğu dev, önce SO'yu kontrol ederek sol JOIN'leri yazamaz.
LAIV

14

Evet, kodlama SQL dizeleri uygulama koduna genellikle bir anti-kalıptır.

Bunu üretim kodunda görerek yıllarca geliştirdiğimiz toleransı bir kenara koymaya çalışalım. Tamamen farklı dilleri aynı dosyada farklı bir sözdizimi ile karıştırmak genellikle arzu edilen bir geliştirme tekniği değildir. Bu, Razor gibi çoklu dillere bağlamsal anlam vermek için tasarlanmış şablon dillerinden farklıdır. As Sava B. altında bir yorumda bahseder, C # veya diğer uygulama dili (Python, C ++, vs.) SQL diğerleri gibi bir dizedir ve anlamsal olarak anlamsızdır. Aynısı, çoğu durumda birden fazla dili karıştırırken de geçerlidir, ancak C'nin satır içi montajı, HTML'de CSS'nin küçük ve anlaşılır snippet'leri (CSS'nin HTML ile karıştırılmak üzere tasarlandığına dikkat çeken) gibi, bunun kabul edilebilir olduğu durumlar olduğu açıktır. ), ve diğerleri.

Robert C. Martin, sf.  288 (Robert C. Martin karıştırma dilleri, Temiz Kod , Bölüm 17, "Kod Kokuları ve Sezgisel", sayfa 288)

Bu yanıt için SQL'e odaklanacağım (soruda sorulduğu gibi). SQL'i alakart olmayan bir dize kümesi olarak saklarken aşağıdaki sorunlar ortaya çıkabilir:

  • Veritabanı mantığını bulmak zor. Tüm SQL ifadelerinizi bulmak için ne ararsınız? "SELECT", "UPDATE", "MERGE" vb.
  • Aynı veya benzer SQL'nin yeniden kullanım kullanımları zorlaşır.
  • Diğer veritabanlarına destek eklemek zordur. Kişi bunu nasıl başarır? Her veritabanı için if..then ifadelerini ekleyin ve tüm sorguları yöntemde dizge olarak saklayın?
  • Geliştiriciler, başka bir dilde bir ifade okur ve odağın, yöntemin amacından yöntemin uygulama detaylarına (verinin nereden ve nereden alındığı) geçmesine odaklanır.
  • Tek gömlekler çok fazla sorun olmasa da, satır içi SQL dizeleri ifadeler daha karmaşık hale geldikçe dağılmaya başlar. 113 satırlı bir ifade ile ne yaparsınız? 113 çizginin hepsini metodunuza eklediniz mi?
  • Geliştirici, sorguları SQL editörleri (SSMS, SQL Developer, vb.) Ve kaynak kodları arasında ileri geri nasıl etkili bir şekilde taşır? C # 'nin @öneki bunu kolaylaştırıyor, ancak her SQL satırından alıntı yapan ve yeni satırlardan kaçan bir sürü kod gördüm. "SELECT col1, col2...colN"\ "FROM painfulExample"\ "WHERE maintainability IS NULL"\ "AND modification.effort > @necessary"\
  • SQL'i çevreleyen uygulama koduyla hizalamak için kullanılan girinti karakterleri, her yürütme sırasında ağ üzerinden iletilir. Bu muhtemelen küçük ölçekli uygulamalar için önemsizdir, ancak yazılımın kullanımı arttıkça eklenebilir.

Tam ORM'ler (Entity Framework veya Hibernate gibi Nesne İlişkisel eşleştiriciler) uygulama kodunda rastgele karabiber SQL'i ortadan kaldırabilir. SQL ve kaynak dosyalarını kullanmam bir örnek. ORM'ler, yardımcı sınıflar vb. Hepsi temiz kodun hedefine ulaşmada yardımcı olabilir.

Kevin'ın daha önceki bir cevabında dediği gibi, koddaki SQL küçük projelerde kabul edilebilir, ancak büyük projeler küçük projeler olarak başlar ve çoğu takımın geri dönme ve bunu doğru yapma olasılığı genellikle kod boyutuyla ters orantılıdır.

SQL'i bir projede tutmanın birçok basit yolu vardır. Sık kullandığım yöntemlerden biri, her SQL ifadesini genellikle "sql" adlı bir Visual Studio kaynak dosyasına koymaktır. Araçlarınıza bağlı olarak bir metin dosyası, JSON belgesi veya başka bir veri kaynağı makul olabilir. Bazı durumlarda, SQL dizelerini birleştirmeye adanmış ayrı bir sınıf en iyi seçenek olabilir, ancak yukarıda açıklanan sorunlardan bazılarına sahip olabilir.

SQL Örnek: Hangisi daha zarif görünüyor ?:

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

Oluyor

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

SQL, her zaman uygulama kodunun akışını kesmeyecek bir yorum için alan içeren, her biri nasıl yapıldığını açıklayan bir açıklayıcı ada sahip, kolayca bulunabilen bir dosyada veya gruplanmış dosya grubundadır :

Kaynaktaki SQL

Bu basit yöntem yalnız bir sorgu yürütür. Tecrübelerime göre, fayda "yabancı dil" in kullanımı olarak daha da artmaktadır. Bir kaynak dosyasını kullanmam sadece bir örnek. Dil (bu durumda SQL) ve platforma bağlı olarak farklı yöntemler daha uygun olabilir.

Bu ve diğer yöntemler yukarıdaki listeyi şu şekilde çözer:

  1. Veritabanı kodu zaten merkezileştiği için bulunması kolaydır. Daha büyük projelerde, like-SQL'i ayrı dosyalar halinde, belki de bir klasör altında toplayın SQL.
  2. İkinci, üçüncü vb. Veritabanları için destek kolaydır. Her veritabanının benzersiz ifadelerini döndüren bir arayüz (veya başka bir dil soyutlama) yapın. Her veritabanı için uygulama, aşağıdakine benzer ifadelerden biraz daha fazlası olur: return SqlResource.DoTheThing;Doğru, bu uygulamalar kaynağı atlayabilir ve SQL'i bir dizgide içerebilir, ancak yukarıdaki bazı sorunların tümü yüzeye çıkacaktır.
  3. Yeniden düzenleme basit - aynı kaynağı tekrar kullanmanız yeterli. Aynı kaynak girişini, çoğu zaman birkaç format ifadesiyle farklı DBMS sistemleri için de kullanabilirsiniz. Bunu sık sık yapıyorum.
  4. İkincil dilin kullanımı açıklayıcı isimler kullanabilir, örneğin sql.GetOrdersForAccountdaha genişSELECT ... FROM ... WHERE...
  5. SQL ifadeleri, boyutlarına ve karmaşıklıklarına bakılmaksızın tek bir satırla toplanır.
  6. SQL, SSMS ve SQL Developer gibi veritabanı araçları arasında değişiklik yapılmadan veya dikkatli bir şekilde kopyalanmadan kopyalanıp yapıştırılabilir. Tırnak işareti yok. Sonunda ters eğik çizgi yok. Özellikle Visual Studio kaynak editörü durumunda, tek bir tıklama SQL deyimini vurgular. CTRL + C tuşlarına basıp ardından SQL editörüne yapıştırın.

Bir kaynakta SQL oluşturulması hızlıdır, bu nedenle kaynak kullanımını kod koduyla karıştırmak için çok az ivme vardır.

Seçilen yönteme bakılmaksızın, karıştırma dillerinin genellikle kod kalitesini düşürdüğünü buldum. Burada açıklanan bazı sorunların ve çözümlerin, geliştiricilerin uygun olduğunda bu kod kokusunu gidermelerine yardımcı olacağını umuyorum.


13
Bunun kaynak kodunda SQL olmanın kötü bir eleştirisine odaklandığını düşünüyorum. Aynı dosyada iki farklı dilin olması mutlaka korkunç değildir. Nasıl bir ilişki içinde oldukları ve her birinin nasıl sunulduğu gibi birçok şeye bağlıdır.
jwg

9
"tamamen farklı dilleri aynı dosyada farklı sözdizimi ile karıştırmak" Bu korkunç bir argümandır. Aynı zamanda Razor görünüm motoru ve HTML, CSS ve Javascript için de geçerlidir. Grafik romanlarını sev!
Ian Newson

4
Bu sadece karmaşıklığı başka bir yere iter. Evet, orijinal kodunuz daha temiz, geliştiricinin şimdi bakım amacıyla yönlendirmesi gereken bir dolaylı ekleme pahasına. Bunu yapmanın asıl nedeni, her SQL ifadesinin kodun birden çok yerinde kullanılmasıydı. Bu şekilde, diğer sıradan yeniden yapılandırmalardan ("Extract method") hiçbir farkı yoktur.
Robert Harvey

3
Daha açık olmak gerekirse, bu "SQL dizelerle ne yapmalıyım" sorusunun cevabı değil, "yeterince karmaşık dizelerin herhangi bir koleksiyonuyla ne yapmalıyım" sorusunun cevabı değil. cevabınız kesinlikle hitap ediyor.
Robert Harvey

2
@RobertHarvey: Deneyimlerimizin farklılık gösterdiğinden eminim ama kendi başıma söz konusu soyutlamayı çoğu durumda bir kazanım olarak buldum. Yıllardır yukarı ve aşağı yaptığım gibi soyutlama değişimlerimi kesinlikle iyileştireceğim ve bir gün SQL'i tekrar kod haline getirebilirim. YMMV. :) Bence mikro hizmetler harika olabilir ve onlar da genel olarak SQL detaylarınızı (eğer SQL kullanılıyorsa) çekirdek uygulama kodundan ayırırlar. Daha az "özel yöntemimi kullan: kaynakları" ve daha çok "Genellikle yağ ve su dillerini karıştırmayın" u savunuculuğunu yapıyorum.
Charles Burns

13

Değişir. İşe yarayabilecek farklı yaklaşımlar var:

  1. SQL'i modülerleştirin ve ayrı bir sınıflar, fonksiyonlar ya da paradigmanızın kullandığı soyutlama birimi kümesine ayırın, ardından uygulama mantığı ile çağırın.
  2. Tüm karmaşık SQL'i görünümlere taşıyın ve ardından uygulama mantığında yalnızca çok basit SQL yapın; böylece hiçbir şeyi modüler hale getirmenize gerek kalmaz.
  3. Bir nesne-ilişkisel eşleme kütüphanesi kullanın.
  4. YAGNI, SQL'i doğrudan uygulama mantığına yaz.

Çoğu zaman olduğu gibi, projeniz zaten bu tekniklerden birini seçtiyse, projenin geri kalanıyla tutarlı olmalısınız.

(1) ve (3), veri tabanını farklı bir satıcı ile değiştirirseniz, uygulama mantığı ve veri tabanı arasındaki bağımsızlığı sağlama konusunda hem nispeten iyidir hem de veri tabanını farklı bir satıcı ile değiştirirseniz, uygulama temel duman testlerini derlemeye ve geçmeye devam eder. Ancak, çoğu satıcı SQL standardına tam olarak uymaz, bu nedenle herhangi bir satıcının başka bir satıcıyla değiştirilmesi, hangi tekniği kullandığınıza bakmaksızın kapsamlı testler ve hata ayıklama gerektirebilir. Bunun, insanların yaptıkları gibi büyük bir anlaşma olduğuna kuşkuluyum. Veritabanlarını değiştirmek, temelde mevcut veritabanını ihtiyaçlarınızı karşılayamayacağınız son çaredir. Bu durumda, muhtemelen veritabanını zayıf bir şekilde seçtiniz.

(1) ve (3) arasındaki seçim, çoğunlukla ORM'leri ne kadar sevdiğinizle ilgilidir. Bence onlar aşırı kullanılıyor. Bunlar ilişkisel veri modelinin zayıf bir temsilidir, çünkü satırların nesnelerin kimliğine sahip olmaları gibi kimlikleri yoktur. Eşsiz kısıtlamalar etrafında acı noktalarıyla karşılaşmanız muhtemeldir, katılır ve ORM'nin gücüne bağlı olarak daha karmaşık bazı soruları ifade etmekte zorlanabilirsiniz. Öte yandan, (1) muhtemelen bir ORM'den çok daha fazla kod gerektirecektir.

(2) tecrübelerime göre nadiren görülür. Sorun, birçok mağazanın SWE'lerin doğrudan veritabanı şemasını değiştirmelerini yasaklamasıdır (çünkü "DBA'nın işi" budur). Bu mutlaka kendi başına bir Kötü Şey değildir; şema değişikliklerinin işleri parçalamak için önemli bir potansiyeli vardır ve dikkatlice dağıtılması gerekebilir. Ancak, (2) 'nin çalışması için, SWE'ler en azından yeni görüşler sunabilmeli ve mevcut görüşlerin destek sorgularını en az bürokrasiyle ya da hiç bürokrasiyle değiştirebilmelidir. İş yerinizde durum böyle değilse, (2) muhtemelen sizin için çalışmayacaktır.

Öte yandan, (2) 'yi çalıştırabilirseniz, diğer çoğu çözümden çok daha iyidir çünkü uygulama kodu yerine ilişkisel mantığı tutar. Genel amaçlı programlama dillerinden farklı olarak SQL, ilişkisel veri modeli için özel olarak tasarlanmıştır ve buna bağlı olarak karmaşık veri sorgularını ve dönüşümlerini ifade etmede daha iyidir. Ayrıca, veritabanlarını değiştirirken görünümler şemanızın geri kalanıyla birlikte gösterilebilir, ancak bu tür hareketleri daha karmaşık hale getirecektir.

Okumak için, saklı prosedürler temelde sadece (2) 'nin bir crappier versiyonudur. Onları bu kapasitede önermiyorum, ancak veritabanınız güncellenebilir görünümleri desteklemiyorsa veya bir defada tek bir satır eklemek veya güncellemekten daha karmaşık bir şey yapmanız gerekiyorsa, yine de yazmak isteyebilirsiniz. işlemler, okuma-yazma-vb.) Saklı yordamınızı bir tetikleyici kullanarak (yaniCREATE TRIGGER trigger_name INSTEAD OF INSERT ON view_name FOR EACH ROW EXECUTE PROCEDURE procedure_name;), ancak görüşler, bunun aslında iyi bir fikir olup olmadığına göre büyük ölçüde değişir. Muhataplar, uygulamanızın çalıştırdığı SQL'i olabildiğince basit tuttuğunu söyleyecektir. Dedektörler, bunun kabul edilemez bir "sihir" seviyesi olduğunu ve sadece doğrudan uygulamanızdan prosedürü uygulamanız gerektiğini söyleyecektir. Ben senin saklı yordam görünüyor veya benzeri bir çok hareket ediyorsa bu daha iyi bir fikir olduğunu söyleyebilirim INSERT, UPDATEya DELETEve daha kötü bir fikir başka bir şey yapıyorsa. Nihayetinde hangi tarzın daha anlamlı olacağı konusunda kendiniz karar vermelisiniz.

(4) çözüm değildir. Küçük projeler için ya da yalnızca veritabanıyla ara sıra etkileşimde bulunan büyük projeler için buna değer olabilir. Ancak çok fazla SQL içeren projeler için bu iyi bir fikir değildir, çünkü uygulamanızın etrafına dağılmış aynı sorgunun kopyalarını veya varyasyonlarını, okunaklılık ve yeniden düzenleme işlemlerine müdahale eder.


2 yazıldığı gibi esasen salt okunur bir veri tabanıdır. Saklı yordamlar, değiştirilen sorgular için nadir değildir.
jpmc26

@ jpmc26: Parantez içindeki yazıları yazıyorum ... bu cevabı geliştirmek için özel bir öneriniz var mı?
Kevin,

Hm. Cevabı tamamlamadan ve yorumdan sonra dikkatini dağıtmadan önce yorum yapmak için özür diler. Ancak güncellenebilir görünümler, bir tablonun güncellendiği yeri bulmayı oldukça zorlaştırır. Güncellemelerin doğrudan tablolarda, mekanizmadan bağımsız olarak sınırlandırılması, kod mantığını anlama açısından avantajlarına sahiptir. Mantığı DB ile sınırlıyorsanız, saklı yordamlar olmadan bunu uygulayamazsınız. Ayrıca, tek bir çağrı ile birden fazla işleme izin verme avantajına da sahiptirler. Alt satır: Onlara göre çok zor olması gerektiğini sanmıyorum.
jpmc26

@ jpmc26: Bu adil.
Kevin,

8

Kaynak kodda SQL yazmak için bir anti-pattern olarak mı kabul edilir?

Şart değil. Buradaki tüm yorumları okursanız, kaynak kodunda hardcoding SQL ifadeleri için geçerli argümanlar bulacaksınız.

Sorun, ifadeleri nereye yerleştirdiğinizle ilgilidir . SQL ifadelerini projenin her yerine, her yere yerleştirirseniz, genellikle takip etmeye çalıştığımız bazı SOLID ilkelerini görmezden geliyor olacaksınız.

demek istediğini varsayalım; ya:

1) LINQ kullanın

veya

2) SQL için saklı yordamları kullanın

Ne demek istediğini söyleyemeyiz. Ancak tahmin edebiliriz. Örneğin, aklıma gelen ilk satıcı kilitlenmesi . Sabit kodlama SQL ifadeleri, uygulamanızı DB motoruna sıkıca bağlamanıza neden olabilir. Örneğin, satıcının ANSI uyumlu olmayan belirli işlevlerini kullanarak.

Bu mutlaka yanlış ne de kötü değil. Ben sadece gerçeği işaret ediyorum.

SOLID ilkelerini ve satıcı kilitlerini gözardı etmek, görmezden gelebileceğiniz olası olumsuz sonuçlara sahiptir. Bu yüzden genellikle ekiple birlikte oturmak ve şüphelerinizi açığa vurmak iyidir.

Saklı yordamların yararı, SQL Geliştiricilerin geliştirme sürecine dahil olabileceğini düşünüyorum (saklı yordamları yazmak vb.)

Saklı yordamlar avantajları ile ilgisi olmadığını düşünüyorum. Dahası, eğer meslektaşınız kodlanmış SQL'den hoşlanmazsa, işi saklı prosedürlere taşımak muhtemelen onu sevmez.

Düzenleme: Aşağıdaki bağlantı kodlanmış SQL ifadeleri hakkında konuşur:  https://docs.microsoft.com/en-us/sql/odbc/reference/develop-app/hard-coded-sql-statements . SQL deyimi hazırlamanın bir faydası var mı?

Evet. Yazı hazırlanan ifadelerin avantajlarını içerir . Bir çeşit SQL şablonlama. Dizelerin birleştirilmesinden daha güvenli. Ancak görev, sizi bu yoldan gitmeye teşvik etmiyor ya da haklı olduğunuzu onaylamıyor. Sadece kodlanmış SQL'i güvenli ve verimli bir şekilde nasıl kullanabileceğimizi açıklar.

Özetle, önce meslektaşınıza sormayı deneyin. Bir mail gönderin, telefon edin, ... Cevaplasın ya da cevaplasın, ekibin yanında oturun ve şüphelerinizi dile getirin. Gereksinimlerinize en uygun çözümü bulun. Orada okuduklarına dayanarak yanlış varsayımlar yapma.


1
Teşekkürler. +1 "Hardcoding SQL deyimleri uygulamanızı db enginee ile sıkıca birleştirmenize yol açabilir.". SQL yerine SQL Server'a atıfta bulunuyorsa dolanıyorum, yani dbConnection yerine SQLConnection kullanıyor; DbCommand yerine SQLCommand ve dbDataReader yerine SQLDataReader.
w0051977

Hayır. ANSI uyumlu olmayan ifadelerin kullanımından bahsediyordum. Örneğin: select GETDATE(), ....GETDATE (), SqlServer'ın tarih işlevidir. Diğer motorlarda, fonksiyonun farklı bir adı, farklı ifadesi vardır ...
Laiv

14
"Satıcı kilitlenmesi" ... İnsanlar / şirketler gerçekte ne kadar sıklıkla var olan ürünlerinin veritabanını başka bir RDBMS'ye geçirir? Sadece ORM kullanan projelerde bile, bunun olduğunu hiç görmedim: genellikle yazılım da sıfırdan yeniden yazılır, çünkü ihtiyaçlar arasında ihtiyaçlar değişmiştir. Bu nedenle, bunu düşünmek bana "erken optimizasyon" gibi gözüküyor. Evet, tamamen öznel.
Olivier Grégoire

1
Ne sıklıkta olduğu umurumda değil. Önemsiyorum, olabilir. Yeşil alan projelerinde, db'den soyutlanmış bir DAL uygulamasının maliyeti neredeyse 0'dır. Olası bir göç değildir. ORM'ye karşı argümanlar oldukça zayıf. ORM'ler, 15 yıl önce Hibernate'in oldukça yeşil olduğu zamanlar gibi değildir. Gördüğüm, bir çok "varsayılan" yapılandırma ve çok daha kötü veri modeli tasarımları. Diğer birçok araç gibi, birçok kişi "başlangıç" dersini veriyor ve kaputun altında ne olacağını umursamıyorlar. Alet sorun değil. Sorun, nasıl ve ne zaman kullanılacağını bilemeyendir.
Laiv

Öte yandan, satıcı kilitlendi mutlaka fena değil. Bana istenirse sevmediğimi söylerdim . Ancak, zaten Spring, Tomcat veya JBoss veya Websphere (hala daha kötü) için kilitli. Bunlardan kaçınabiliyorum. Yapamadığımları sadece onunla yaşayabiliyorum. Tercihler meselesi.
18'de Laiv

3

Bence bu kötü bir uygulama, evet. Diğerleri, tüm veri erişim kodunuzu kendi katmanında tutmanın avantajlarına dikkat çekti. Etrafında avlanmak zorunda değilsiniz, optimize etmek ve test etmek daha kolay ... Ama bu katman içinde bile birkaç seçeneğiniz var: bir ORM kullanın, sprocs kullanın veya SQL sorgularını dizge olarak gömün. SQL sorgu dizgilerinin en kötü seçenek olduğunu söyleyebilirim.

Bir ORM ile, geliştirme çok daha kolay ve daha az hataya açık hale gelir. EF ile şemanızı, yalnızca model sınıflarınızı oluşturarak tanımlayabilirsiniz (bu sınıfları oluşturmaya ihtiyacınız olurdu). LINQ ile sorgulamak bir esinti - sık sık bir sproc yazmak ve korumak istediğiniz 2 satır c # ile kaçıyorsunuz. IMO, verimlilik ve bakım kolaylığı söz konusu olduğunda büyük bir avantaja sahip - daha az kod, daha az sorun. Fakat ne yaptığınızı bilseniz bile, genel bir performans var.

Sprocs (veya işlevler) diğer seçenektir. Burada, SQL sorgularınızı el ile yazın. Ama en azından doğru olduklarının garantisi var. .NET'te çalışıyorsanız, SQL geçersizse, Visual Studio derleyici hataları bile atar. Bu harika. Bazı sütunları değiştirir veya kaldırırsanız ve bazı sorgularınız geçersiz hale gelirse, en azından derleme sırasında bunu öğrenmeniz muhtemeldir. Sprocs'u kendi dosyalarında tutmak çok daha kolaydır - muhtemelen sözdizimi vurgulama, otomatik tamamlama ... vb.

Sorgularınız sprocs olarak saklanırsa, uygulamayı yeniden derlemeden ve yeniden dağıtmadan da bunları değiştirebilirsiniz. SQL'inizdeki bir şeyin bozulduğunu fark ederseniz, bir DBA uygulama kodunuza erişmenize gerek kalmadan düzeltebilir. Genel olarak, eğer sorgularınız string değişmezlerdeyse, dbas işlerini bu kadar kolay yapamazsınız.

Dize değişmezleri olarak SQL sorguları, veri erişiminizi c # kodunu daha az okunabilir hale getirir.

Sadece bir kural olarak, sihirli sabitler kötüdür. Bu dize değişmezleri içerir.


DBA'ların uygulamayı güncellemeden SQL'inizi değiştirmesine izin vermek, uygulamanızı etkili bir şekilde ayrı, ayrı olarak dağıtılmış iki ayrı öğeye ayırmaktır. Şimdi bunlar arasındaki arayüz sözleşmesini yönetmeniz, birbirine bağlı değişikliklerin serbest bırakılmasını senkronize etmeniz, vb. Yapmanız gerekiyor. Bu iyi bir şey veya kötü bir şey olabilir, ancak "tüm SQL'inizi tek bir yere koymaktan" çok daha fazlası - mimari karar alma.
IMSoP

2

Bu bir anti-patern değildir (bu cevap tehlikeli bir şekilde fikre yakındır). Ancak kod biçimlendirme önemlidir ve SQL dizesi biçimlendirilmeli, böylece onu kullanan koddan açıkça ayrı olmalıdır. Örneğin

    string query = 
    @"SELECT foo, bar
      FROM table
      WHERE id = @tn";

7
Bununla ilgili en göze batan sorun, bu değerin 42 nereden geldiği konusudur. Bu değeri dizgede birleştiriyor musunuz? Eğer öyleyse, nereden geldi? SQL enjeksiyon saldırılarını azaltmak için nasıl temizlendi? Bu örnek neden parametreli hale getirilmiş bir sorgu göstermiyor?
Craig

Sadece biçimlendirmeyi göstermek istemiştim. Üzgünüm, parametreleştirmeyi unuttum. Şimdi msdn.microsoft.com/library/bb738521(v=vs.100).aspx
adresini ziyaret

Biçimlendirmenin önemi için +1 olsa da, SQL dizelerinin biçimlendirmeden bağımsız olarak bir kod kokusu olduğunu savunuyorum.
Charles Burns

1
ORM kullanımı konusunda ısrar ediyor musunuz? Bir ORM kullanılmadığında, daha küçük bir proje için, gömülü SQL içeren 'shim' sınıfını kullanırım.
17’de

SQL dizeleri kesinlikle bir kod kokusu değil. Bir ORM olmadan, bir yönetici ve mimar olarak, hem bakım hem de bazen performans nedenleriyle onları SP'ler konusunda teşvik ederim.
Sentinel

1

Size meslektaşınızın ne anlama geldiğini söyleyemem. Ancak buna cevap verebilirim:

SQL deyimi hazırlamanın bir faydası var mı?

EVET . Sınırlı değişkenlerle hazırlanmış beyannamelerin kullanılması , on yıldan fazla bir süredir web uygulamaları için en büyük güvenlik riski olmaya devam eden SQL enjeksiyonuna karşı önerilen savunmadır . Bu saldırı o kadar yaygındır ki, yaklaşık on yıl önce web çizgi romanlarında gösterilmişti ve etkili savunmaların dağıtıldığı zamandır.

... ve sorgu dizelerinin hatalı bir şekilde birleştirilmesinde en etkili savunma, sorguları en başta dizeler olarak göstermek değil, sorgular oluşturmak için güvenli bir sorgu API'si kullanmaktır. Örneğin, sorgunuzu Java’da QueryDSL ile nasıl yazacağım:

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

Gördüğünüz gibi, burada tek bir dize değişmez, bu da SQL enjeksiyonunu imkansız kılıyor. Dahası, bunu yazarken kod tamamladım ve IDE'mi yeniden tanımlayabiliyorum, id sütununu yeniden adlandırmayı seçmem gerekir. Ayrıca, persondeğişkene erişildiği IDE'yi sorarak kişi tablosu için tüm sorguları kolayca bulabilirim . Oh, ve gözlerde kodunuzdan biraz daha kısa ve daha kolay olduğunu fark ettiniz mi?

Sadece böyle bir şeyin C # için de geçerli olduğunu varsayabilirim. Mesela LINQ hakkında harika şeyler duyuyorum.

Özetle, sorguları SQL dizeleri olarak göstermek, IDE'nin sorguları yazmaya ve sorgulamaya anlamlı bir şekilde yardım etmesini, derleme zamanından çalışma zamanına kadar sözdizimi tespitini ve tip hatalarını savunmasını zorlaştırır ve SQL enjeksiyon zayıflıklarına neden olan bir nedendir [1]. Bu yüzden evet, birinin kaynak kodda SQL dizeleri istememesinin geçerli nedenleri olabilir.

[1]: Evet, hazırlanan ifadelerin doğru kullanılması ayrıca SQL enjeksiyonunu da önler. Ancak bu konudaki bir başka cevabın, bir yorumcu bunu vurgulayana kadar, genç programcılara güven duyulmadığını vurgulayana kadar bir SQL enjeksiyonuna karşı savunmasız olduğunu ...


Açık olması: Hazırlanan ifadeleri kullanmak SQL enjeksiyonunu engellemez. Sınırlı değişkenlerle hazırlanmış deyimler kullanmak. Güvenilmeyen verilerden oluşturulan hazır ifadeler kullanmak mümkündür.
Andy Lester

1

Burada bir sürü harika cevap var. Zaten söylenenlerin yanı sıra, bir şey daha eklemek istiyorum.

Satır içi SQL bir anti-pattern kullanmayı düşünmüyorum. Bununla birlikte, bir anti-patern olduğunu düşündüğüm şey, her programcının kendi işini yaptığıdır. Ortak bir standartta bir takım olarak karar vermelisiniz. Herkes linq kullanıyorsa, o zaman linq kullanırsınız, eğer herkes görüş ve saklı yordamlar kullanıyorsa, bunu yaparsınız.

Her zaman açık fikirli olun ama dogmanın üzerine düşmeyin. Eğer dükkanınız "linq" bir dükkan ise, onu kullanırsınız. Linq'in kesinlikle çalışmadığı bir yer hariç. (Ama zamanın% 99,9'unu yapmamalısın.)

Öyleyse yapacağım kod kod tabanında araştırma yapmak ve meslektaşlarınızın nasıl çalıştığını kontrol etmek.


+1 İyi nokta. Desteklenebilirlik, diğer pek çok kaygılardan daha önemlidir, bu yüzden çok akıllı olmayın :) Eğer bir ORM mağazasıysanız, ORM'nin cevap olmadığı ve doğrudan SQL yazmanız gereken durumlar olduğunu unutmayın. Zamanından önce optimizasyon yapmayın, ancak önemsiz olan herhangi bir uygulamada, bu rotadan aşağı inmeniz gerekecek zamanlar olacaktır.
mcottle

0

Kod, veritabanı ile kodun geri kalanı arasındaki veritabanı etkileşim katmanından görünüyor. Eğer öyleyse, bu anti-patern değildir .

Bu yöntem, OP farklı düşünüyor olsa bile katmanın bir parçasıdır (düz veritabanı erişimi, başka hiçbir şey ile karıştırılmaması). Belki de sadece kodun içine kötü bir şekilde yerleştirilmiş. Bu yöntem ayrı sınıfa, "veritabanı arayüz katmanı" na aittir. Veritabanı dışı etkinlikleri uygulayan yöntemlerin yanına sıradan bir sınıfa yerleştirmek anti-patern olur.

Anti-patern, başka bir rastgele kod yerinden SQL'i aramak olacaktır. Veri tabanı ile kodun geri kalanı arasında bir katman tanımlamanız gerekir, ancak bu konuda size yardımcı olabilecek bazı popüler araçları kesinlikle kullanmanız gerekmez.


0

Bence hayır , anti bir model değil ama özellikle tek bir satıra sığamayan büyük sorgular için kendinizi dize biçimlendirme aralığıyla uğraşırken bulacaksınız.

Bir başka artı, belli şartlara göre inşa edilmesi gereken dinamik sorgularla uğraşırken daha da zorlaşıyor.

var query = "select * from accounts";

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

Bir sql sorgu oluşturucu kullanmanızı öneririm


Sadece kısayol kullanıyor olabilirsiniz, ancak "SELECT *" yi kör bir şekilde kullanmak gerçekten kötü bir fikirdir, çünkü gerekmeyen alanları geri getireceksiniz (bant genişliği!) Ayrıca şartlı Admin cümlesiyle bir sorunum olmamasına rağmen koşullu bir “NEREDE” yan tümcesine çok kaygan bir eğim aşağıya iner ve bu doğrudan performans cehenneme giden bir yoldur.
mcottle

0

Kod değişikliklerinin derlenebileceği, test edilebileceği ve dakikalar içinde üretime gönderilebildiği hızlı dağıtım boru hatları olan birçok modern organizasyon için, SQL ifadelerini uygulama koduna gömmek tamamen mantıklı geliyor. Bu mutlaka nasıl gittiğine bağlı olarak bir anti-patern değildir.

Günümüzde saklı yordamları kullanmak için geçerli bir durum, haftalar süren QA döngüleri vb. İçerebilecek üretim dağıtımları hakkında çok fazla işlemin olduğu kuruluşlardadır. Bu senaryoda, DBA ekibi, yalnızca ilk üretim dağıtımından sonra ortaya çıkan performans sorunlarını optimize ederek çözebilir. saklı yordamlarda sorgular.

Bu durumda değilseniz, SQL'inizi uygulama kodunuza gömmenizi öneririm. Bu konudaki en iyi yol hakkında öneri almak için bu konudaki diğer cevapları okuyun.


Bağlam için aşağıdaki orijinal metin

Saklı yordamların en büyük avantajı, uygulamanızı yeniden derlemeden ve yeniden dağıtmadan veritabanı performansını optimize edebilmenizdir.

Birçok kuruluşta, kod yalnızca günler veya haftalar sürebilen bir KG işleminden sonra üretime itilebilir. Sisteminiz, kullanım modellerini değiştirmek veya masa boyutlarında vb. Artışlar nedeniyle bir veritabanı performans sorunu geliştirirse, zor kodlanmış sorgularla sorunu tespit etmek oldukça zor olabilir, oysa veritabanında problemi saklı yordamları tanımlayacak araçlar / raporlar vb. . Depolanan prosedürlerle çözümler üretimde test edilebilir / kıyaslanabilir ve uygulama yazılımının yeni bir versiyonunu zorlamadan sorun hızla çözülebilir.

Bu sorun sisteminizde önemli değilse, o zaman uygulamanın içine SQL ifadeleri kodlamak için mükemmel bir karardır.


Yanlış ...........
Sentinel

Yorumunuzun kimseye yararlı olduğunu düşünüyor musunuz?
bikeman868

Bu sadece düz yanlış. Diyelim ki veri erişimi olarak EF, depolama alanı olarak Azure Sql ile EF ile bir Web API2 projemiz var. Hayır, EF'den kurtulalım ve el yapımı SQL kullanalım. Db şeması, bir SSDT SQL Server projesinde saklanır. Azure.B'deki bir kod değişikliği, 2 saniye süren bir App Service dağıtım yuvasına gönderilmeyi içerir. Ayrıca el yapımı SQL, aksine bilgeliğe rağmen, genel olarak konuşulan saklı yordamlar üzerinde performans artığına sahiptir.
Sentinel

Sizin durumunuzda konuşlandırma işlemi birkaç saniye sürebilir, ancak bu çoğu insan için geçerli değildir. Saklı işlemlerin daha iyi olduğunu, sadece bazı durumlarda bazı avantajları olduğunu söylemedim. Son ifadem, eğer bu koşullar geçerli değilse, uygulamaya SQL koyarak çok geçerli olduğu yönündedir. Bu ne söylediğinle çelişiyor?
bikeman868

Saklı yordamlar el yapımı SQL ???
bikeman868
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.