2016-04-06 17 views
1

İşte bir sorun. Aşağıdaki kod, bir xml değişkeninden bazı satırları silmek için bir çalışma yöntemini göstermektedir. Amaç, primaryKey özniteliğine sahip olmayan satırların, eskiValue ve newValue özniteliklerinin aynı olduğu 1 olarak ayarlanmasıdır. (Aynı demek istediğim, her ikisi de null veya her ikisi de aynı değere sahip olabilir) Aşağıdaki kod bu durumu göstermektedir. Ancak, aşağıdaki kod bir imleci kullanır. Tek bir @ xml.modify kullanarak ya da en azından imleci kullanmaya başvurmak zorunda kalmadan silme işlemini gerçekleştirmek mümkün olsaydı beni şaşırtmazdı.xml'den etkin düğümleri silin

declare @xml xml ='<changes schemaName="Security" tableName="AccessProfiles"> 
    <column name="AccessProfileId" primaryKey="1" oldValue="114" newValue="114" /> 
    <column name="AccessProfileName" oldValue="test" newValue="Testing" /> 
    <column name="DeleteMeSame" oldValue="testValue" newValue="testValue" /> 
    <column name="DeleteMeNull" /> 
    <column name="KeepMePrimaryNull" primaryKey="1" /> 
    <column name="KeepMePrimarySame" primaryKey="1" oldValue="sameValue" newValue="sameValue"/> 
</changes>'; 

declare @columnName sysname; 

declare deleteNodesCursor cursor fast_forward for 
    with shreddedXml as (
     select 
      N.value('@name' , 'sysname') as name, 
      N.value('@primaryKey' , 'bit') as primaryKey, 
      N.value('@oldValue' , 'varchar(max)') as oldValue, 
      N.value('@newValue' , 'varchar(max)') as newValue 
     from @xml.nodes('/changes/column') as T(N) 
    ) 
    select 
     Name 
    from shreddedXml 
    where primaryKey is null 
    and (oldValue = newValue 
    or (oldValue is null and newValue is null)) 

open deleteNodesCursor 

while (1=1) 
begin 
    fetch next from deleteNodesCursor into @columnName 
    if @@fetch_status != 0 
     break; 

    set @xml.modify('delete /changes[1]/column[@name= sql:variable("@columnName")]') 
end; 

close deleteNodesCursor; 
deallocate deleteNodesCursor; 

select @xml 

Özet olarak, soru şu ki, bunu nasıl verimli bir şekilde yapabilirim?

cevap

1

"niyet OLDVALUE ve newValue nitelikleri aynıdır 1'e, ayarlı primaryKey niteliği. (Yani aynı tarafından yok satırları silmek için, hem null veya her ikisine birden sahip olabilir aşağıdaki gibi tek @xml.modify ifadesi tercüme edilebilir aynı değer)"

(test edilmiş ve) SQL Server 2008R2 çalıştı:

set @xml.modify('delete /changes/column[not(@primaryKey=1) and not(@[email protected])]') 
+1

Kapat. hala var ve olmamalıdır. Ama bence problemi çözecek ve çözecek kadar verdin. –

+0

@ColinDawson ah, haklısın! Cevabımı – har07

+0

kapsayacak şekilde güncelledim, yukarıdaki xml'yi aldım ve bu şekilde değiştirdim. set @ xml.modify ('delete/changes/column [not (@ primaryKey = 1) ve ((@ eskiValue = @ newValue) veya (boş (@oldValue) ve boş (@ newValue)))') –