SQL Server'daki bir görünümdeki bir sütuna başvuran bir yabancı anahtar alabilir miyim?


85

SQL Server 2008'de verilen

TableA(A_ID, A_Data)
TableB(B_ID, B_Data)
ViewC(A_or_B_ID, A_or_B_Data)

Bu tanımlamak mümkündür TableZ(A_or_B_ID, Z_Data)şekilde Z.A_or_B_IDsütun içinde bulunan değerlere sınırlıdır ViewC? Bu görüşe karşı yabancı bir anahtarla yapılabilir mi?

Yanıtlar:


110

Yabancı anahtardaki bir görünüme başvuruda bulunamazsınız.


38
bu bir SQL sunucusunun bir sınırlaması mı yoksa mantıksız bir şey mi?
Aaron Anodide

1
@Brian Bunun bir SQL Server sınırlaması mı yoksa mantıksız bir şey mi olduğunu bilmek isterim çünkü bu noktada sadece FK desteği almak için tetikleyicileri kullanarak bir görünümü taklit etmek üzereyim (ancak MySql kullanıyorum ).
Kızak

4
Bu, aşağıdaki takip sorularına iyi bir cevaptır - stackoverflow.com/questions/3833150/…
Chris Halcrow

Bunun bu sorulara nasıl iyi bir cevap olduğundan emin değilim ... farklı bir DBMS ile ilgili ve görünümlerin şema ayrıntılarını ve kullanıcı rahatlığını gizlemek için tasarlandığını söylüyor. Öncelikle, tamam ... ama bu, ilk tasarımın ötesinde sağlam kullanım alanları bulan ilk şey olmayacak. İkinci olarak, bir FK'nin bunu neden yapmayacağından emin değilim. Bir görünüm, bir tablodan çizmesi gerekmeyen herhangi bir sorgu olabilir, bir araya getirilmiş bir grup sabit olabilir ... bu durumda bir yabancı anahtar oldukça mantıklı görünür. Daha derin bir şey ummamam için bir sebep varsa.
George Mauer

27

Eski SQL Server sürümlerinde yabancı anahtarlar yalnızca tetikleyiciler aracılığıyla mümkündü. Eklenen değerin ilgili tablolardan birinde görünüp görünmediğini kontrol eden bir Ekleme tetikleyicisi oluşturarak özel bir yabancı anahtarı taklit edebilirsiniz.


3
StackOverflow'a hoş geldiniz. Bir geçici çözüm sağladığı için cevabınızda bir değer buldum, ancak doğru cevap kabul edilen cevaptır ve soru 4 yıldan daha eski, bu yüzden sadece oy kullanmıyorum ama bu yorum olmadan ayrılmak istemedim.
jachguate

16

A_or_B_IDTableZ'de gerçekten ihtiyacınız varsa, iki benzer seçeneğiniz vardır:

1) Tablo z'ye null yapılabilir A_IDve B_IDsütunlar ekleyin A_or_B_ID, bu iki sütunda ISNULL kullanarak hesaplanan bir sütun oluşturun ve yalnızca biri A_IDveya B_IDboş olmayacak şekilde bir DENETİM kısıtlaması ekleyin

2) Tablo z'ye, A veya B'yi içerecek şekilde kısıtlanmış bir TableName sütunu ekleyin. Şimdi A_IDve B_IDhesaplanan sütunlar olarak, yalnızca uygun tabloları adlandırıldığında (CASE ifadesini kullanarak) boş olmayanlar oluşturun. Onların da ısrar etmesini sağlayın

Her iki durumda da, artık temel tablolara uygun yabancı anahtarlara sahip olabilen A_IDve B_IDsütunlarınız vardır. Fark, sütunların hesaplandığı yerdir. Ayrıca, 2 kimlik sütununun alanları çakışmıyorsa yukarıdaki 2. seçenekte TableName'e ihtiyacınız yoktur - vaka ifadeniz hangi alanın A_or_B_ID dahil olduğunu belirleyebildiği sürece

(Biçimlendirmemi düzelttiğim için yorum için teşekkürler)


Arka A_or_B_ID
tiklere

Eski bir sisteme bazı özellikler eklemek için çalışıyorum ve bu, eski ve yeniyi bir araya getirmenin harika bir yolu. Teşekkür ederim!
David Gunderson


4

Başka bir seçenek daha var. TableA ve TableB'yi TablePrime adlı yeni bir tablonun alt sınıfları olarak ele alın. TableB'nin kimlik değerlerini, TableA'nın kimlik değerleriyle çakışmayacak şekilde ayarlayın. TablePrime'daki ID'yi PK yapın ve tüm TableA'lar ve TableB'lerin (ayarlanmış) ID'lerini TablePrime'a ekleyin. TableA ve TableB'nin, TablePrime'daki aynı ID'ye kendi PK'ları üzerinde FK ilişkileri olmasını sağlayın.

Artık süper tip / alt tip modeline sahipsiniz ve TablePrime ( ya-A-veya-B istediğinizde ) veya tek tek tablolardan biri ( sadece A veya sadece B istediğinizde) için kısıtlamalar yapabilirsiniz .

Daha fazla ayrıntıya ihtiyacınız varsa lütfen sorun. A ve B'nin birbirini dışlamasını sağlamanıza izin verecek varyasyonlar vardır veya belki birlikte çalıştığınız şey aynı anda ikisi de olabilir. Mümkünse bunu FK'lerde resmileştirmek en iyisidir.


2

Sizin için kontrolü yapan kullanıcı tanımlı bir işleve, değer varsa doğru, yoksa yanlış döndüren fCheckIfValueExists (columnValue) 'ye başvuran bir kısıt eklemek daha kolaydır.

Bunun tersi, birden çok sütun alabilir, bunlarla hesaplamalar yapabilir, boş değerleri kabul edebilir ve bir birincil anahtara tam olarak karşılık gelmeyen veya birleştirmelerin sonuçlarıyla karşılaştırmayan değerleri kabul edebilir.

Dezavantajı, optimize edicinin tüm yabancı anahtar hilelerini kullanamamasıdır.


1
Dezavantajı, optimize edicinin tüm yabancı anahtar hilelerini kullanamaması ... ... ve işlevin eklediğiniz / güncellediğiniz her satır için çalıştırılacağıdır (bu nedenle setler için çok iyi değildir).
jimbobmcgee

1

Üzgünüz, kelimenin tam anlamıyla, hayır, görünümlere yabancı anahtarlar ayarlayamazsınız. İşte nedeni:

InnoDB, MySQL için yabancı anahtarlar içeren tek yerleşik depolama motorudur. Herhangi bir InnoDB tablosu information_schema.tables'da engine = 'InnoDB' ile kaydedilecektir.

Görünümler information_schema.tables dosyasında kayıtlıyken, NULL depolama motoruna sahiptir. MySQL'de tanımsız bir depolama motoruna sahip herhangi bir tabloda yabancı anahtarlara sahip olmak için bir mekanizma yoktur.

Teşekkürler!


bu soru sql server ile ilgili
George Mauer
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.