2

たとえば、次のようなxml列があります。

<mi>
  <m>42</m>
</mi>

テーブルを想定:

Word(WordId:bigint, Wordtext:nvarchar, MessageIndex:xml)

@MessageIdがMessageindexのxmlツリーのどこかにすでに存在する場合、次のパラメーター化されたクエリで新しいxmlノードを挿入したくありませんが、決定論的なエラーコードで失敗するか、サイレントに失敗します。

begin try
    insert into Word (WordText, MessageIndex) values (@WordText, '<mi></mi>');
    update Word set MessageIndex.modify('insert (<m>{sql:variable(""@MessageId"")}</m>) into(/mi)[1]') where WordId = scope_identity();
end try
begin catch
    if error_number() = 2627
    begin
        update Word set
            MessageIndex.modify('insert (<m>{sql:variable(""@MessageId"")}</m>) into(/mi)[1]')
        where
            WordText = @WordText;
    end
    else
        throw
end catch

WordからWordIdを選択します。ここでWordText=@WordText;

これを効率的に行うにはどうすればよいですか?

4

2 に答える 2

3

このようなものはあなたのために働きますか?

DECLARE @Word TABLE (WordId bigint identity, Wordtext NVARCHAR(20), MessageIndex xml ) 

insert into @word ( messageIndex )
select '<mi> 
  <m>42</m> 
</mi>'

DECLARE @WordText NVARCHAR(20) = 'wordText'
DECLARE @messageId INT = 42

begin try 

    if exists ( select 1 from @Word where MessageIndex.exist('//mi[.=sql:variable("@MessageId")]') = 0 )
    begin
        insert into @Word (WordText, MessageIndex) values (@WordText, '<mi></mi>'); 

        update @Word set MessageIndex.modify('insert <m>{sql:variable("@MessageId")}</m> into (mi)[1]') 
        where WordId = scope_identity(); 

    end
    --else
        -- do something here?

end try 
begin catch 
    if error_number() = 2627 
    begin 
        update @Word set MessageIndex.modify('insert <m>{sql:variable("@MessageId")}</m> into (mi)[1]') 
        where WordText = @WordText; 
    end 
    else 
        throw 
end catch 

select * from @Word
于 2012-09-19T00:12:10.893 に答える