2011-07-07 1 views
2

に基づいて、いくつかのXML属性を変更します。私がやりたい何 SQL Server XML add attribute if non-existent前のポストからリスト

すると、複数のタグを変更することが可能です。以下は、私が何をしたいのかを示すコードですが、エラーが出るので、できません。XMLデータ型のメソッド "exists"の引数1は文字列リテラルでなければなりません。リテラルではなく変数を使用してXMLを変更する方法はありますか?

ALTER FUNCTION [dbo].[ConvertXmlData](@xmlData XML) 
RETURNS XML 
AS 
BEGIN 

    DECLARE @tags TABLE (
     ID INT IDENTITY(1,1) NOT NULL PRIMARY KEY, 
     TAG VARCHAR(25) 
    ) 

    INSERT INTO @tags 
    SELECT 'xxx' UNION 
    SELECT 'yyy' 

    DECLARE @counter INT 
    DECLARE @count INT 
    DECLARE @id  INT 
    DECLARE @tag  VARCHAR(25) 
    DECLARE @exist VARCHAR(100) 
    DECLARE @insert VARCHAR(100) 
    DECLARE @existX VARCHAR(100) 
    DECLARE @insertX VARCHAR(100) 

    SET @exist = 'descendant::{0}[not(@runat)]' 
    SET @insert = 'insert attribute runat { "server" } into descendant::{0}[not(@runat)][1]' 
    SET @counter = 1 
    SELECT @count = COUNT(*) FROM @tags 

    WHILE @counter <= @count BEGIN 

     SELECT @tag = TAG FROM @tags WHERE ID = @counter 
     SET @existX = REPLACE(@existX, '[0]', @tag) 
     WHILE @xmlData.exist(@existX) = 1 BEGIN 
     SET @xmlData.modify(REPLACE(@insertX, '[0]', @tag)); 
     END 

     SET @counter = @counter + 1 
    END  

    RETURN @xmlData 
END 

答えて

2

は、XML関数の引数として変数を使用することはできませんが、あなたはリテラル式中の変数(とテーブルの列)を使用することができます。

私はこれがあなたが望むことをすると思います。少なくとも、あなたができることのアイデアを与えるべきです。

declare @xmlData xml 
set @xmlData = 
'<something> 
    <xxx id="1"/> 
    <xxx id="2" runat="server" /> 
    <xxx id="3"/> 
    <yyy id="3" /> 
    <zzz id="1"/> 
</something>' 

declare @tags table 
(
    id int identity(1,1) primary key, 
    tag varchar(25) 
) 

insert into @tags 
select 'xxx' union 
select 'yyy' 

declare @tag varchar(25) 
declare @id int 

select top 1 
     @id = id, 
     @tag = tag 
from @tags 
order by id 

while @@rowcount > 0 
begin 
    while @xmlData.exist('descendant::*[local-name() = sql:variable("@tag") and not(@runat)]') = 1 
    begin 
    set @xmlData.modify('insert attribute runat { "server" } into descendant::*[local-name() = sql:variable("@tag") and not(@runat)][1]'); 
    end 

    select top 1 
     @id = id, 
     @tag = tag 
    from @tags 
    where id > @id 
    order by id 
end  

select @xmlData 

結果:

<something> 
    <xxx id="1" runat="server" /> 
    <xxx id="2" runat="server" /> 
    <xxx id="3" runat="server" /> 
    <yyy id="3" runat="server" /> 
    <zzz id="1" /> 
</something> 
+0

素晴らしいです!正確に私が必要としたもの。 –