2012-06-29 6 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 ОТНОСИТЬСЯ используется. Может ли кто-нибудь предложить обходное решение для этого? Поскольку работа с такими представлениями, которые не индексируются, слишком медленна, когда речь идет о более высоких объемах данных XML.

EDIT:

Есть ли способ, которым я мог бы индекс сам XML?

+0

Вы уверены, что любые функции XML поддерживаются с индексированными представлениями? Существуют серьезные ограничения на то, что вы можете использовать. – usr

+0

Существует хорошее правило - если вы нашли один способ написать запрос для достижения определенного набора результатов, а запрос является незаконным в индексированном представлении, то любым другим способом вы можете написать запрос для достижения того же результата set также будет незаконным. (хорошо, могут быть исключения, но я не встречал многих из них) –

+1

Re: Edit - вы просмотрели ['CREATE 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; 
Смежные вопросы