2009-04-14 71 views
-1

我有基於短信的調查應用程序,它接受調查域和答案。在SQL Server 2005中處理這個約束的最好方法是什麼?

我已經得到了詳細的DDL請求,所以....數據庫看起來像this

SurveyAnswer.Answer必須全部活躍調查爲SurveyDomain中是唯一的。在SQL而言,這應該總是返回0..1行:

select * from survey s, surveyanswer sa 
where s.surveyid = sa.surveyid and 
     s.active = 1 and 
     s.surveydomainid = @surveydomainid 
     sa.answer = @answer 

我打算在應用層處理這一約束,但也想了一些數據庫的完整性來執行。做這個的最好方式是什麼?觸發?可能在一個約束?

+0

你能提供DDL嗎?你的主鍵是什麼? – 2009-04-14 19:34:59

+0

我以最簡單的方式添加了DDL ...... :) – TheSoftwareJedi 2009-04-14 20:52:55

回答

2

由於您正在覆蓋2個表,所以AFAIK只有2種方法來執行此操作。

  1. 按照您的建議觸發。
  2. 索引視圖與3列中的唯一約束。

就可靠性而言,我會選擇索引視圖,但唯一的缺點是它很難被第三方理解。

0

假設您正在使用存儲過程來執行DML操作,您可以向SP添加一個警戒子句,它爲調查添加答案以檢查是否存在等效答案。然後,您可以拋出異常或返回狀態碼來指示無法添加答案。

1

它可以添加在一個UDF實現這樣的約束:

alter table MyTable add constraint complexConstraint 
check (dbo.complexConstraintFct()=0) 

凡complexConstraintFct將包含對其他表的查詢功能。然而,這種方法有一些問題,因爲檢查約束被設計爲一次在單個行上進行評估,但更新一次可以影響更多的行。所以,底線是:堅持觸發器

0

不能在行級(如CHECK約束)做,所以你必須有東西,可以查看所有行

觸發器可以發送「好」的消息,但他們DML語句後運行。您可以很好地控制處理。

索引視圖阻止DML語句,但它提供了技術錯誤消息。這是一個額外的對象和索引來維護。

-1

我想你說的是,對於任何活動的問題,元組(surveyDomain,surveyQuestion,surveyAnswer)必須是唯一的?或者換句話說,調查:如果調查是活躍的,調查問卷是1:1,即使調查:調查問卷設置爲1:很多。

如果是這樣,答案是改變你的表格結構。向調查添加一個可爲空的activeAnswerId列將有效地使關係1:1;您現有的約束唯一的SurveyId(或唯一的SurveyId,SurvetDomainId)將足以實施唯一性。事實上,除非我誤解,否則我很驚訝調查有一個問題欄;我希望Survey:Question是1:很多(一項調查有很多問題),甚至很多:如果一個問題可以在多個調查中顯示出來。更一般地說,我懷疑弄清楚如何執行約束是很困難的,並且需要像觸發器或用戶定義函數那樣的「英雄」,這是模式的一個症狀,它不能準確地建模問題域。

OP評論:

沒有,你就錯過了。調查:答案是1:n。 「問題」是調查問題 - 元組將是(SurveyDomain.SurveyDomainId,Survey.Answer)

您的意思是說,對於每個域,最多隻有一個答案?再一次,看看你的模式,最好是誤導。 SurveyDomain有很多調查(每個調查都有一個問題欄),調查有很多答案? (Schema

但是,如果調查的活動位被設置,應該只有一個答案?

調查問題是否使用不當?

這真的不清楚你想要建模什麼。

同樣,如果難以添加約束,則表明您的模型不起作用。

相關問題