2012-06-29 46 views
0
CREATE TABLE Storage 
(
    ID INT IDENTITY(1,1) PRIMARY KEY, 
    data XML NOT NULL 
) 

GO 

INSERT INTO Storage(data) 
VALUES(' 
<footballteams> 
    <team manager="Benitez">  
     <name>Liverpool</name>  
     <ground>Anfield</ground> 
    </team> 
    <team manager="Mourinho">  
     <name>Chelsea</name>  
     <ground>Stamford Bridge</ground> 
    </team> 
    <team manager="Wenger">  
    <name>Arsenal</name>  
     <ground>Highbury</ground> 
    </team> 
</footballteams>'); 
---------------------------------------- 
GO 

CREATE VIEW FootballView WITH SCHEMABINDING AS 
( 
    SELECT    
     TeamName = Team.TeamNode.value('(name)[1]', 'varchar(100)'),    
     Manager = Team.TeamNode.value('(@manager)', 'varchar(100)'),    
     Ground = Team.TeamNode.value('(ground)[1]', 'varchar(100)')  
    FROM   
     dbo.Storage S   
     CROSS APPLY DATA.nodes('/footballteams') AS Teams(TeamsNode) 
     CROSS APPLY data.nodes('/footballteams/team') AS Team(TeamNode) 
) 
GO 
CREATE UNIQUE CLUSTERED INDEX TeamNameInd ON FootballView(TeamName) 

-創建的SQL Server索引視圖2008

Error Message: Cannot create index on view "CF.dbo.FootballView" because it contains an APPLY. Consider not indexing the view, or removing APPLY. 

我意識到,實際上,索引不能爲這個視圖中創建,因爲CROSS APPLY使用。 任何人都可以提出解決類似的問題?作爲一個享有這樣的未編入索引的工作是當它與XML數據的更大量涉及太慢。

編輯:

有什麼辦法我可以索引XML本身?

+0

您確定索引視圖支持任何XML功能嗎?你可以使用什麼有嚴格的限制。 – usr

+0

有一個很好的經驗法則 - 如果您發現編寫一個查詢,以實現特定的結果集的一種方式,並且查詢在索引視圖非法的,那麼任何其他方式,你可以編寫查詢來達到同樣的效果設置也將是非法的。 (好吧,也有例外,但我從來沒有遇到過很多人) –

+1

回覆:編輯 - 你有研究['創建XML INDEX'(http://msdn.microsoft.com/en-us/library/ bb934097)在MSDN上? –

回答

1

通過將XML數據解析到SQL關係表中,並通過使用簡單的觸發器使表保持同步,您可以解決此問題(,並可能獲得更好的性能)。以下腳本是如何完成的示例,我希望它對您的案例有用:

CREATE TABLE Storage (
    id INT IDENTITY(1,1) PRIMARY KEY, 
    data XML NOT NULL 
); 

CREATE TABLE FootballTable (
    id INT, 
    teamName varchar(100), 
    manager varchar(100), 
    ground varchar(100) 
); 
GO 

CREATE TRIGGER TG_INS_Storage ON Storage 
FOR INSERT, UPDATE, DELETE AS 
BEGIN 
    DELETE FootballTable WHERE id IN (SELECT dlt.id FROM deleted dlt); 

    INSERT FootballTable (id, teamName, manager, ground) 
    SELECT ins.id, 
    TeamName = Team.TeamNode.value('(name)[1]', 'varchar(100)'), 
    Manager = Team.TeamNode.value('(@manager)', 'varchar(100)'), 
    Ground = Team.TeamNode.value('(ground)[1]', 'varchar(100)') 
    FROM inserted ins 
    CROSS APPLY ins.data.nodes('/footballteams/team') AS Team(TeamNode); 
END 

INSERT INTO Storage(data) 
VALUES(' 
<footballteams> 
    <team manager="Benitez"><name>Liverpool</name><ground>Anfield</ground></team> 
    <team manager="Mourinho"><name>Chelsea</name><ground>Stamford Bridge</ground></team> 
    <team manager="Wenger"><name>Arsenal</name><ground>Highbury</ground></team> 
</footballteams>'); 
GO 
SELECT * FROM FootballTable;