İşte benim senaryom:
Benim bir proje için yerelleştirme üzerinde çalışıyorum ve genellikle benim SQL biraz buff çalışıyorum çünkü ben biraz daha SQL'de bunu yapmak istiyorum, ancak ben C # kodunda bunu hakkında gitmek istiyorum.
Ortam: SQL Server 2014 Standard, C # (.NET 4.5.1)
Not: Programlama dilinin kendisi alakasız olmalı, sadece tamlık için dahil ediyorum.
Bu yüzden istediğimi başardım, ama istediğim ölçüde değil. JOINTemel olanlar dışında SQL'ler yaptığımdan beri bir süre (en az bir yıl) oldu ve bu oldukça karmaşık JOIN.
İşte veritabanının ilgili tablolarının bir diyagramı. (Bu bölüm için çok daha fazlası var, ancak gerekli değil.)

Resimde açıklanan tüm ilişkiler veritabanında tamamlanmıştır - PKve FKkısıtlamaların hepsi kurulum ve işletimdir. Açıklanan sütunların hiçbiri nullmümkün değil. Tüm tabloların şeması vardır dbo.
Şimdi, neredeyse ne istediğimi yapan bir sorgu var : yani, herhangi bir kimliği SupportCategoriesve herhangi bir kimliği verildi Languages, ya da dönecektir:
Bu dizi için bu dil (Ie için sağ doğru çeviri varsa StringKeyId-> StringKeys.Idvar ve içinde LanguageStringTranslations StringKeyId, LanguageIdve StringTranslationIdkombinasyon daha sonra yükler, mevcut StringTranslations.Textbunun için StringTranslationId.
Eğer LanguageStringTranslations StringKeyId, LanguageIdve StringTranslationIdkombinasyon vermedi DEĞİL var, o zaman yükler StringKeys.Namedeğeri. Languages.IdBir verilir integer.
Sorgu, karışıklık olsun, aşağıdaki gibidir:
SELECT CASE WHEN T.x IS NOT NULL THEN T.x ELSE (SELECT
CASE WHEN dbo.StringTranslations.Text IS NULL THEN dbo.StringKeys.Name ELSE dbo.StringTranslations.Text END AS Result
FROM dbo.SupportCategories
INNER JOIN dbo.StringKeys
ON dbo.SupportCategories.StringKeyId = dbo.StringKeys.Id
INNER JOIN dbo.LanguageStringTranslations
ON dbo.StringKeys.Id = dbo.LanguageStringTranslations.StringKeyId
INNER JOIN dbo.StringTranslations
ON dbo.StringTranslations.Id = dbo.LanguageStringTranslations.StringTranslationId
WHERE dbo.LanguageStringTranslations.LanguageId = 38 AND dbo.SupportCategories.Id = 0) END AS Result FROM (SELECT (SELECT
CASE WHEN dbo.StringTranslations.Text IS NULL THEN dbo.StringKeys.Name ELSE dbo.StringTranslations.Text END AS Result
FROM dbo.SupportCategories
INNER JOIN dbo.StringKeys
ON dbo.SupportCategories.StringKeyId = dbo.StringKeys.Id
INNER JOIN dbo.LanguageStringTranslations
ON dbo.StringKeys.Id = dbo.LanguageStringTranslations.StringKeyId
INNER JOIN dbo.StringTranslations
ON dbo.StringTranslations.Id = dbo.LanguageStringTranslations.StringTranslationId
WHERE dbo.LanguageStringTranslations.LanguageId = 5 AND dbo.SupportCategories.Id = 0) AS x) AS T
Sorun şu ki beni sağlama yeteneğine olmadığıdır TÜM ait SupportCategoriesve kendi StringTranslations.Textvarsa, YA onların StringKeys.Nameo olmasaydı. Bunlardan herhangi birini sağlamak mükemmel, ama hiç değil. Temel olarak, bir dilin belirli bir anahtar için çevirisi yoksa, varsayılanın StringKeys.Namehangisinin StringKeys.DefaultLanguageIdçeviri olduğunu kullanmaktır . (İdeal olarak, bunu bile yapmaz, bunun yerine çeviriyi yükler, bunun yerine StringKeys.DefaultLanguageIdsorgunun geri kalanı için doğru yönde işaret edersem kendim yapabilirim.)
Ben bu konuda çok zaman geçirdim, ve ben sadece C # (genellikle yaptığım gibi) yazacak olsaydı şimdiye kadar yapılacaktı biliyorum. Bunu SQL'de yapmak istiyorum ve sevdiğim çıktıyı almakta sorun yaşıyorum.
Tek uyarı, uygulanan gerçek sorgu sayısını sınırlamak istiyorum. Tüm sütunlar dizine eklenmiştir ve şimdilik onları beğendim ve gerçek stres testi olmadan bunları daha fazla dizine ekleyemiyorum.
Düzenleme: Başka bir not, ben mümkün olduğunca normalleştirilmiş veritabanı tutmak için çalışıyorum, bu yüzden ben önleyebilirsiniz şeyler çoğaltmak istemiyorum.
Örnek Veriler
Kaynak
dbo.SupportCategories (Tamamen):
Id StringKeyId
0 0
1 1
2 2
dbo.Languages (185 kayıt, örnekler için sadece iki tane gösterilmektedir):
Id Abbreviation Family Name Native
38 en Indo-European English English
48 fr Indo-European French français, langue française
dbo.LanguagesStringTranslations (Entirety):
StringKeyId LanguageId StringTranslationId
0 38 0
1 38 1
2 38 2
3 38 3
4 38 4
5 38 5
6 38 6
7 38 7
1 48 8 -- added as example
dbo.StringKeys (Tamamen):
Id Name DefaultLanguageId
0 Billing 38
1 API 38
2 Sales 38
3 Open 38
4 Waiting for Customer 38
5 Waiting for Support 38
6 Work in Progress 38
7 Completed 38
dbo.StringTranslations (Entirety):
Id Text
0 Billing
1 API
2 Sales
3 Open
4 Waiting for Customer
5 Waiting for Support
6 Work in Progress
7 Completed
8 Les APIs -- added as example
Akım Çıkışı
Aşağıdaki kesin sorgu göz önüne alındığında, çıktı:
Result
Billing
Istenilen çıktı
İdeal olarak, belirli bir şeyi atlamak SupportCategories.Idve hepsini elde etmek istiyorum, böylece ( şu anda 38 dilinin Englishkullanılıp kullanılmadığına veya 48 Frenchveya şu anda HERHANGİ başka bir dil kullanılmasına bakılmaksızın ):
Id Result
0 Billing
1 API
2 Sales
Ek Örnek
French(Ie add ) için bir yerelleştirme eklemek 1 48 8için LanguageStringTranslationsverildiğinde, çıkış olarak değişecektir (not: bu sadece örnektir, açıkçası yerelleştirilmiş bir dize ekleyeceğim StringTranslations) (Fransızca örnekle güncellendi):
Result
Les APIs
Ek İstenen Çıktı
Yukarıdaki örnek göz önüne alındığında, aşağıdaki çıktı istenecektir (Fransızca örnekle güncellenmiştir):
Id Result
0 Billing
1 Les APIs
2 Sales
(Evet, teknik olarak bunun tutarlılık açısından yanlış olduğunu biliyorum, ancak bu durumda istenen şey budur.)
Düzenle:
Küçük güncellendi, dbo.Languagestablonun yapısını değiştirdim ve Id (int)sütunu ondan bıraktım ve onunla değiştirdim Abbreviation(şimdi yeniden adlandırıldı Idve tüm göreceli Yabancı Anahtarlar ve ve ilişkiler güncellendi). Teknik açıdan bakıldığında, tablonun başlangıçta benzersiz olan ISO 639-1 kodları ile sınırlı olması nedeniyle bu daha uygun bir kurulum.
Tl, Dr.
Yani: Soru, nasıl dönüş için bu sorguyu değiştirebilir şeyi gelen SupportCategoriesve ardından ya dönmek StringTranslations.Textbunun için StringKeys.Id, Languages.Idkombinasyonu, yaStringKeys.Name da eğer DEĞİL var?
İlk düşüncem, bir şekilde geçerli sorguyu başka bir alt sorgu olarak başka bir geçici sorguya atabiliyor ve bu sorguyu başka bir SELECTifadeye sarıp istediğim ( SupportCategories.Idve Result) iki alanı seçebileceğim .
Bir şey bulamazsam, sadece tipik olarak tüm SupportCategoriesC # projeme yüklemek için kullandığım standart yöntemi yapacağım ve sonra onunla her birine karşı el ile yukarıdaki sorguyu çalıştırın SupportCategories.Id.
Her türlü öneri / yorum / eleştiri için teşekkürler.
Ayrıca saçma sapan bir şey olduğu için özür dilerim, herhangi bir belirsizlik istemiyorum. Sık sık StackOverflow üzerinde ve madde eksikliği, burada bu hata yapmak istemiyordu soruları görmek.
