2011-06-08 55 views
0

当我们加载到游标的XML,然后我们指定列名称及其数据类型和大小。而不是手动指定如何使该区域动态。假设我的TSQL这里如下关于动态SQL构建

Exec sp_xml_preparedocument @XMLFormat OUTPUT, @DetailXml 

-- Create Cursor from XML Table 

Declare CurDetailRecord 
Cursor For 
Select productid,unit,rate,qty,amount 
From Openxml (@XMLFormat, '/NewDataSet/PurchaseOrderDetail', 2) 
With 
(
productid Varchar(10), 
unit Varchar(50), 
rate decimal(18,2), 
qty decimal(18,3), 
amount decimal(18,2) 
) 

的例子

productid Varchar(10), 
unit Varchar(50) 

等我正在指定,也tyoe &大小指定其数据。

那么我怎么能动态地构造这个区域并动态获取列名和数据类型的大小&。

请指导我谢谢。

回答

1

你可以列名(这是PurchasePrderDetail节点内部节点)是这样的:

declare @xml xml='<NewDataSet><PurchaseOrderDetail> 
<productid>19125</productid> 
</PurchaseOrderDetail></NewDataSet>' 
SELECT b.value('local-name(.)','nvarchar(128)')ColumnName, 
    LEN(b.value('.','nvarchar(128)'))MaxLength 
FROM @xml.nodes('/NewDataSet/PurchaseOrderDetail/*') a(b) 

所以,你可以生成动态SQL语句创建具有适当列名称和长度的光标,如varchar(MaxLength)。

但是,如果不知道真正的列名称,就无法从XML获取数据类型,因为xml中的数据只是文本和f.e. “5”可以是int类型,也可以是文本。

编辑

如果您知道表名,你可以建造使用使用元数据从该表中动态SQL语句如下:

; With cols as(
SELECT COLUMN_NAME, 
UPPER(DATA_type) 
+ 
case when data_type like '%char' then 
    case when CHARACTER_MAXIMUM_LENGTH=-1 THEN ' (MAX)' 
    else ' ('+CAST(CHARACTER_MAXIMUM_LENGTH as nvarchar)+')' 
    END 
ELSE '' 
END ColConv 
FROM INFORMATION_SCHEMA.COLUMNS 
WHERE TABLE_NAME='PurchaseOrderDetail'), 
XMLS as(
SELECT b.value('local-name(.)','nvarchar(128)')ColumnName, 
    b.value('.','nvarchar(128)')Value 
FROM @xml.nodes('/NewDataSet/PurchaseOrderDetail/*') a(b) 
) 
SELECT XMLS.ColumnName,'CAST ('''+XMLS.Value+''' AS '+ ColConv+''')' FROM XMLS 
JOIN cols ON XMLS.ColumnName=cols.COLUMN_NAME 

正如输出,你将有列名和值与适当CAST条款。然后你可以建立你所需要的动态声明。

+0

有一个名为PurchaseOrderDetail的表,其中列的相同数目没有被定义.....我们不能从那里获取列数据类型并动态地生成整个使用子句,其中列名,数据类型和大小将被提及。 – Thomas 2011-06-09 10:32:54

0

通常数据类型和字段名称的信息在XSD文件(XML架构定义)中描述。

因此,您需要为每个XML文件都有一个有效的XSD文件,然后才能检索字段名称和数据类型。

Here a link to understand better the XSD

And here how to deal with XSD and XML step by step

希望它可以帮助你

+0

有一个名为PurchaseOrderDetail的表,其中列的相同数目没有被定义.....我们不能从那里获取列数据类型并动态地生成整个使用子句,其中列名,数据类型和大小将被提及。 – Thomas 2011-06-09 10:33:17