在sql server 2005中迭代XML数据

Roh*_*nsi 1 sql-server-2005

我有一个接受的storedprocedure

@MissingRecordsXML NTEXT
Run Code Online (Sandbox Code Playgroud)

它包含XML记录.现在,另一位开发人员使用游标从OPENXML获取行,然后在每行上应用了所有业务规则,然后将每行插入表中.

我想知道在SQL Server中预测XML数据的最佳方法是哪种.我必须提高此SP的性能,因为当有多个记录时它很慢.Cursors已经被声明为只读.请帮助

从XML填充游标的代码是: -

exec sp_xml_preparedocument @hDocSEC OUTPUT,@MissingRecordsXML  

DECLARE SEC_UPDATE CURSOR  FOR  
SELECT MissingColumn,TableName,PhysicalColName,Grantor_Grantee  
FROM OPENXML (@hDocSEC,'MissingDS/MissingTable',2)  
WITH (MissingColumn VARCHAR(1000),TableName VARCHAR(100),  
PhysicalColName VARCHAR(100),Grantor_Grantee VARCHAR(100) )  
OPEN SEC_UPDATE  
FETCH NEXT FROM SEC_UPDATE  
INTO @MissingColumn,@TableName,@ActualColumnName,@Grantor_Grantee 
Run Code Online (Sandbox Code Playgroud)

mar*_*c_s 5

假设您的示例XML看起来像这样:

<MissingDS>
  <MissingTable>
    <MissingColumn>abc</MissingColumn>
    <TableName>tblMyTable</TableName>
    <PhysicalColName>table_abc</PhysicalColName>
    <Grantor_Grantee>nobody</Grantor_Grantee>
  </MissingTable>
  <MissingTable>
    <MissingColumn>xyu</MissingColumn>
    <TableName>tblMyTable2</TableName>
    <PhysicalColName>table_xyz</PhysicalColName>
    <Grantor_Grantee>nobody2</Grantor_Grantee>
  </MissingTable>
</MissingDS>
Run Code Online (Sandbox Code Playgroud)

然后你可以使用新的SQL Server 2005 XQuery支持解析这个:

DECLARE @MissingXML XML
SET @MissingXML = CAST(@MissingRecordsXML AS XML)

SELECT
    Missing.Rec.value('(MissingColumn)[1]', 'varchar(1000)') AS 'MissingColumn',
    Missing.Rec.value('(TableName)[1]', 'varchar(100)') AS 'TableName',
    Missing.Rec.value('(PhysicalColName)[1]', 'varchar(100)') AS 'Physical',
    Missing.Rec.value('(Grantor_Grantee)[1]', 'varchar(100)') AS 'Grantor_Grantee'
FROM
    @MissingXML.nodes('/MissingDS/MissingTable') AS Missing(Rec)
Run Code Online (Sandbox Code Playgroud)

当然,如果你可以选择它,你也可以很容易地将相同的数据行插入表中:

INSERT INTO 
  dbo.MissingDSTable(MissingColumn, TableName, PhysicalColName, Grantor_Grantee)
    SELECT
       Missing.Rec.value('(MissingColumn)[1]', 'varchar(1000)') AS 'MissingColumn',
       Missing.Rec.value('(TableName)[1]', 'varchar(100)') AS 'TableName',
       Missing.Rec.value('(PhysicalColName)[1]', 'varchar(100)') AS 'Physical',
       Missing.Rec.value('(Grantor_Grantee)[1]', 'varchar(100)') AS 'Grantor_Grantee'
    FROM
       @MissingXML.nodes('/MissingDS/MissingTable') AS Missing(Rec)
Run Code Online (Sandbox Code Playgroud)

希望这个对你有帮助

  • 好吧,在SQL中,你**不应该逐行循环.SQL是基于集合的** - 在集合中思考,集合行动,处理集合 - 不要回退到逐行处理..... (2认同)