2013-10-07 51 views
1

中選擇的表格當前我有一個帶有「控制」列的單個表格。該表通常包含兩組數據,活動組和舊組。數據更新時,表格將包含活動集和新集。一旦數據被更新,控制變量就會被切換,並且新的組變成活動組,並且先前活動的組變成舊組。每天一次,舊的設置被刪除,新的設置被創建。此操作由幾個中間步驟組成,通常需要幾個小時。問題是當新的數據集創建時,在活動集上的選擇將超時。我添加了(nolock)這些選項,但這似乎沒有幫助。如何動態控制視圖從

爲了克服這個問題,我現在的計劃是有兩個具有相同定義的表格。活動集將在一個表中,舊/新集將在另一個表中。我想要做的是有一個視圖將根據控制值從一個表或另一個表中選擇數據。

我的控件是一個包含Id列和進度列的表。進入表格基本上是:

SELECT d.* FROM MyData d 
JOIN ControlTable c ON c.ID = d.Control 
WHERE c.Progress = 1000 -- 1000 is active 

我該如何設置一個視圖來查看一個表或另一個表取決於控件?我的希望是我可以將MyData從表格更改爲視圖,這樣我的大部分代碼都不會受到影響。

回答

2

創建一個同義詞。

CREATE SYNONYM dbo.MyData FOR dbo.MyActiveData; 

然後,當你正在做維修或已切換或者你有什麼:

DROP SYNONYM dbo.MyData; 
CREATE SYNONYM dbo.MyData FOR dbo.MyPassiveData; 

現在你的觀點可以直接引用dbo.MyData但實際上重定向到一個或另一個表條件。請注意,如果行數/數據在幾天之間波動很大,這不是真正的優化器友好。

+0

這個唯一的'缺點'是每次(重新)創建同義詞時,都需要重新應用安全性。而且,當你開始查詢元數據時,同義詞需要相當多的時間! (sys.columns等) – deroby

+0

@deroby爲什麼你需要將安全性應用於同義詞?爲什麼不只是基礎表? –

+0

這是否工作?去測試它......聽起來反直覺。 – deroby

1

這項工作?

CREATE VIEW myView 
AS 
SELECT t.* FROM myTable1 t JOIN myControlTable c ON c.pk = 1 AND c.value = 1 

UNION ALL 

SELECT t.* FROM myTable2 t JOIN myControlTable c ON c.pk = 1 AND c.value = 2 

您可能需要添加WITH(NOLOCK)作爲'其他'MyTable可能會在您處理它時被鎖定。

另一種解決方案是在兩個表之間交換數據。這樣你總是會有一個'主動'表和一個'工作'表。 =>你的「報告」始終着眼於活動表 =>您的「處理」看起來總是在工作表

然後使用ALTER TABLE SWITCH命令這一點。通常意味着用於分區,但我相信它也可以在兩個相同的表之間使用。

恕我直言,這將是一個更好的解決方案,因爲您的報告或處理都不需要具有「動態」代碼,但始終指向同一個表。

一些示例代碼來說明我的意思:

-- cleanup 
IF OBJECT_ID('myTable1') IS NOT NULL DROP TABLE myTable1 
IF OBJECT_ID('myTable2') IS NOT NULL DROP TABLE myTable2 
IF OBJECT_ID('swapTable') IS NOT NULL DROP TABLE swapTable 

GO 
-- creat 3 identical tables 
CREATE TABLE myTable1 (pk  int IDENTITY(1, 1) NOT NULL 
          CONSTRAINT pkTable1 PRIMARY KEY (pk), 
         value int  NULL) 

CREATE TABLE myTable2 (pk  int IDENTITY(1, 1) NOT NULL 
          CONSTRAINT pkTable2 PRIMARY KEY (pk), 
         value int  NULL) 

CREATE TABLE swapTable (pk  int IDENTITY(1, 1) NOT NULL 
          CONSTRAINT pkSwapTable PRIMARY KEY (pk), 
         value int  NULL) 

-- insert some data 
INSERT myTable1 (value) VALUES (123) 
INSERT myTable1 (value) VALUES (456) 
INSERT myTable2 (value) VALUES (-1) 


-- current situation 
SELECT info = 'MyTable1', * FROM myTable1 
SELECT info = 'MyTable2', * FROM myTable2 

-- swap tables around 
TRUNCATE TABLE swapTable 
ALTER TABLE myTable1 SWITCH TO swapTable 

TRUNCATE TABLE myTable1 
ALTER TABLE myTable2 SWITCH TO myTable1 

TRUNCATE TABLE myTable2 
ALTER TABLE swapTable SWITCH TO myTable2 

GO 
-- new situation 
SELECT info = 'MyTable1', * FROM myTable1 
SELECT info = 'MyTable2', * FROM myTable2 
0

感謝您對那些誰回答。

我沒有找到任何答案很滿意,所以我一直在調查一些選項。我提出的看起來很合理,但我希望看到它的評論。

首先我添加了一列來包含哪些表使用到控制表。接下來,我設置了兩組數據的視圖(假設兩個表:MyData_1和MyData_2)

CREATE VIEW MyData AS 
    SELECT d.* FROM MyData_1 d, Control c WHERE c.Progress = 1000 AND c.[Table] = 'MyData_1' 
UNION ALL 
    SELECT d.* FROM MyData_2 d, Control c WHERE c.Progress = 1000 AND c.[Table] = 'MyData_2' 

,我看到的缺點,是我將需要更新所有選擇所述活動組中的代碼從

SELECT d.* FROM MyData d 
JOIN ControlTable c ON c.ID = d.Control 
WHERE c.Progress = 1000 -- 1000 is active 

SELECT d.* FROM MyData d 

這是非常相似的@ deroby的初步答案。我證實,在非活動數據集上存在鎖定時,查詢將工作。

+0

請不要使用像'FROM t1,t2'這樣陳舊,危險的語法 - 你在問題中有一個'JOIN',爲什麼你在回答中變得懶惰(這跟@ deroby的答案是一樣的無論如何)? –

+0

我不明白爲什麼這是危險的,但無論如何,有兩個表格,真的沒有理由再有一個控制列,因此沒有什麼可以加入。 – Russ

+0

那麼爲什麼你的觀點提到兩張表? http://sqlblog.com/blogs/aaron_bertrand/archive/2009/10/08/bad-habits-to-kick-using-old-style-joins.aspx –