2011-06-08 52 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