2016-12-15 3 views
1

カーソルを使用して各行にXMLファイルを生成しています。私はxml_temp_tableからIDのリストを選択しています。次に、これらのXMLファイルを別のテーブル(LOCATION_TABLE_XML)で更新する必要があります。私は更新するために20Kを超える行がある場合、このカーソルが効率的ではないことに気付きました。ありがとう、本当に感謝しています。カーソルを使用せずにXMLを生成し、SQL Serverのテーブルで更新する

 DECLARE @xml_var XML; 
    DECLARE @ID INT; 
    DECLARE XML_CURSOR CURSOR FOR 
    SELECT id 
    FROM xml_temp_table 
    WHERE id IS NOT NULL; 

    OPEN XML_CURSOR; 
    FETCH NEXT 
    FROM XML_CURSOR 
    INTO @ID; 

WHILE @@FETCH_STATUS = 0 
BEGIN 
SET @xml_var = 
(
    SELECT 
      (
        SELECT 'Type' AS ID, 
          'Initial' AS VALUE, 
          ''  AS TAG, 
          'true' AS VISIBLE, 
          Getdate() AS HISTORY, 
          ''  AS DESCRIPTION, 
          ''  AS COMMENT 
        FROM XML_TABLE d 
        WHERE D.XML_ID = @ID FOR XML PATH('field'), 
          TYPE) AS '[*]', 
      (
        SELECT 'OwnerName' AS ID, 
          'Testing_XML' AS VALUE, 
          ''   AS TAG, 
          'true'  AS VISIBLE, 
          Getdate()  AS HISTORY, 
          ''   AS DESCRIPTION, 
          ''   AS COMMENT 
        FROM XML_TABLE d 
        WHERE D.XML_ID = @ID FOR XML PATH('field'), 
          TYPE) AS '[*]' 
    FROM XML_TABLE p 
    WHERE P.XML_ID = @ID FOR XML PATH('Material'), 
      ROOT('FormValue')); 
UPDATE S 
SET S.XML_COL = @xml_var, 
FROM LOCATION_TABLE_XML S 
WHERE S.ID = @ID; 

FETCH NEXT 
    FROM XML_CURSOR 
    INTO @ID; 

    END; 

必要な出力確認のため

<FormValue> 
<Material> 
    <field> 
    <id>Type</id> 
    <value>Initial</value> 
    <tag /> 
    <visible>true</visible> 
<history>2016-11-08</history> 
<description /> 
<comment /> 
</field> 
<field> 
    <id>OwnerName</id> 
    <value>Testing_XML</value> 
    <tag /> 
    <visible>true</visible> 
    <history>2016-11-08</history> 
<description /> 
<comment /> 
</field> 
</Material> 
</FormValue> 

答えて

2

一つのこと:あなたがここにCURSORを必要としない...

カーソルが悪いと悪です...彼らはによって発明されています悪魔のデベロッパーたちは、貧しい開発者たちをの設定ベースの光から離して導くことを考えて、と思っています。私がテストを盗まれました(... CURSORが正しい選択であるが、これらは稀であるところ、まあ、いくつかの例があります)... 手続き痛みの暗いエーカーに

あなたを引き下げていますジョンCappelettiからのシナリオ(THXジョン+ Dます...!)、これは単純化することができると思う:

CROSS APPLYための必要性無し... XMLは、それが直接使用することができますスカラー値であるため。そしてCTEとして戻っ@YourTableからCTEに参加する必要は、それ自体、更新がないです:

Declare @YourTable table (ID int,Active bit,First_Name varchar(50),Last_Name varchar(50),EMail varchar(50),XMLData xml) 
Insert into @YourTable values 
(1,1,'John','Smith','[email protected]',null), 
(2,0,'Jane','Doe' ,'[email protected]',null) 

;with cte as 
(
    Select A.ID 
      ,A.XMLData 
      ,( 
        -- This would be your XML generation 
        -- Notice the reference to A.ID 
        Select XMLData = (Select * From @YourTable Where ID=A.ID For XML Path('root')) 
      ) AS NewXML 
    From @YourTable A 
) 
Update cte Set XMLData = NewXML; 

Select * from @YourTable 

しかし、これはさらに簡単に置くことができます。私たちはテーブルのエイリアスを必要があると思いますので、私は、物理的に今のテーブルを作成する必要がありますそれ以外の場合は...

CREATE TABLE YourTable(ID int,Active bit,First_Name varchar(50),Last_Name varchar(50),EMail varchar(50),XMLData xml); 
Insert into YourTable values 
(1,1,'John','Smith','[email protected]',null), 
(2,0,'Jane','Doe' ,'[email protected]',null); 

UPDATE YourTable SET XMLData= ( 
           -- This would be your XML generation 
           Select x.* From YourTable AS x Where x.ID=YourTable.ID For XML Path('root') 
           ) 

Select * from YourTable 
GO 

DROP TABLE YourTable; 

注意1:私はあなたがIDのリストに、このプロセスをフィルタリングする必要があるxml_temp_tableからIDのリストを選択するよあなたの文章を理解しています。もしそうなら、単に追加

WHERE YourTable.ID IN(SELECT filter.ID FROM SomeWhere AS filter) 

注意2:あなたがこれらの行を作成にしたい場合は、文は、その後、私は別のテーブルにこれらのXMLファイルを更新する必要が ...私には明確ではありません

INSERT INTO OtherTable(col1,col2,...) SELECT col1,col2, ... FROM ... 

他のテーブルに与えられたIDの対応する行がある場合、これに対応するステートメントを簡単に変更することができます。助けが必要な場合は、ちょうど戻ってくる...

+0

うん、もう一度それを考え直してください。あなたの物語に役立つと思わない限り、私は恥を取り除きました。 –

関連する問題