2013-03-19 59 views
0

這是我第一次使用XML將數據插入到表中。我將數據從前端(所有Datagridview行)保存到xml文件並將其發送到數據庫插入表SD_ShippingDetails.Below是用於讀取XML數據和保存數據的查詢。您可以從查詢中看到,我將刪除相關的ShippingID詳細信息並再次插入。(DELETE FROM SD_ShippingDetails WHERE ShippingID = @ ShippingID)。可以通過從XML中獲取數據更新SD_ShippingDetails中已有的行。如果是,請幫助我查詢。使用XML數據更新數據庫中的行

CREATE PROCEDURE SD_Insert_ShippingDetails  
@PBMXML as varchar(Max),  
@ShippingID as INT  

AS  
BEGIn  


declare @i int  

exec sp_xml_preparedocument @i output,@PBMXML  



DELETE FROM SD_ShippingDetails WHERE [email protected]  


INSERT INTO SD_ShippingDetails(ShippingID,Weight,Height,TotalBoxes,Price)  
SELECT ShippingID,Weight,Height,TotalBoxes,Price FROM OPENXML(@i,'Root/ShippingBox',2)  
WITH (  
ShippingID int,Weight varchar(20),Height varchar(20),TotalBoxes varchar(20),Price numeric(18,2))  



exec sp_xml_removedocument @i  

END 

謝謝。

+0

可以填充你的XML數據到一個臨時/變量表,然後使用合併插入/更新現有的表。你知道如何做到這一點? – 2013-03-19 18:38:08

+0

嗨,夥伴,你可以幫助我的查詢'米不知道這樣做。 – Prathap 2013-03-19 18:40:56

+0

您需要提供一些XML。 – granadaCoder 2013-03-19 18:44:40

回答

1

您是SQL Server 2005上,所以你可以使用XML數據類型,而不是OPENXML所以這個答案將使用代替。對於解決方案,使用XML數據類型不是必需的。如果你願意,你可以使用openxml重寫。

您在註釋中指定SD_ShippingDetails中存在ID標識字段(我假設這是主鍵),但您也表示ShippingID和Weight的組合是唯一的。這給我們留下了一張看起來像這樣的表格結構。

create table dbo.SD_ShippingDetails 
(
    ID int identity primary key, 
    ShippingID int not null, 
    Weight varchar(20) not null, 
    Height varchar(20), 
    TotalBoxes varchar(20), 
    Price numeric(18,2), 
    unique (ShippingID, Weight) 
); 

的存儲過程首先需要更新已在SD_ShippingDetails存在的所有行之後,它需要插入缺少的行。

create procedure dbo.SD_Insert_ShippingDetails 
    @PBMXML as xml 
as 

update dbo.SD_ShippingDetails 
set Height = T.N.value('(Height/text())[1]', 'varchar(20)'), 
    TotalBoxes = T.N.value('(TotalBoxes/text())[1]', 'varchar(20)'), 
    Price = T.N.value('(Price/text())[1]', 'numeric(18,2)') 
from @PBMXML.nodes('Root/ShippingBox') as T(N) 
where ShippingID = T.N.value('(ShippingID/text())[1]', 'int') and 
     Weight = T.N.value('(Weight/text())[1]', 'varchar(20)'); 

insert into dbo.SD_ShippingDetails(ShippingID, Weight, Height, TotalBoxes, Price) 
select T.N.value('(ShippingID/text())[1]', 'int'), 
     T.N.value('(Weight/text())[1]', 'varchar(20)'), 
     T.N.value('(Height/text())[1]', 'varchar(20)'), 
     T.N.value('(TotalBoxes/text())[1]', 'varchar(20)'), 
     T.N.value('(Price/text())[1]', 'numeric(18,2)') 
from @PBMXML.nodes('Root/ShippingBox') as T(N) 
where not exists (
       select * 
       from dbo.SD_ShippingDetails 
       where ShippingID = T.N.value('(ShippingID/text())[1]', 'int') and 
         Weight = T.N.value('(Weight/text())[1]', 'varchar(20)') 
       ); 

SQL Fiddle

+0

嗨Mikael ..你拯救了我的一天。它效果很好。 – Prathap 2013-03-20 19:02:49

+0

對於沒有意識到的dotnet開發人員的一個小建議。我想當我們用XML參數創建StoredProcedure時,我們不需要將前端的參數作爲XElement(這是XML類型)發送。將參數設置爲SQLDBTYPE.XML並值作爲字符串。 – Prathap 2013-03-20 19:06:25

0

如果您有Sql Server 2005,那麼將值放在#temp或@variables表中是最好的。

隨着2008年及以後,您可以搭上MERGE功能。

http://msdn.microsoft.com/en-us/library/bb522522(v=sql.105).aspx

這裏是一個很好的鏈接,XML分解。請注意,您正在使用舊版本的OPENXML。這是一個更多的Sql Server 2000命令。檢查Plamen的博客下面的2005年和以上的語法。

http://pratchev.blogspot.com/2007/06/shredding-xml-in-sql-server-2005.html

+0

嗨,感謝隊友,儘管我並沒有完全理解我寫的這個查詢。作爲緊急事項,我從網上覆制了它,並且它的工作正常。我已經通過這個鏈接,並且不太瞭解。我會嘗試找到一種使用鏈接編寫更新查詢的方法。 – Prathap 2013-03-19 18:48:01

+0

第1步是讓你的數據進入@變量或#temp表。我會先從@變量表開始。步驟2然後執行UPDATE ......並將實際表格的PK與@variable表格的PK(主鍵)相匹配。是的,更新匹配的行比刪除所有內容並重新插入更好。 – granadaCoder 2013-03-19 19:15:00

+0

我不知道如何實現這一點。而不是使用XML概念,如果我通過在前端循環插入Datagridview的每一行,會怎樣?它會影響性能嗎?有一點可以肯定的是,對數據庫的調用次數會增加。 – Prathap 2013-03-20 03:08:23

0

我會填充XML到一個變量表,然後使用Update聲明和InsertNot Exists

如果你有SQL 2008,你可以取代你的刪除和插入這個語句...

MERGE SD_ShippingDetails AS Target 
USING (SELECT ShippingID, 
       Weight, 
       Height, 
       TotalBoxes, 
       Price 
     FROM OPENXML(@i,'Root/ShippingBox',2)  
       WITH (ShippingID int, 
         Weight varchar(20), 
         Height varchar(20), 
         TotalBoxes varchar(20), 
         Price numeric(18,2))) AS source (ShippingID,Weight,Height,TotalBoxes,Price) 
     ON (target.ShippingID = source.ShippingID) 
WHEN MATCHED THEN 
     UPDATE SET Weight = source.Weight, 
        Height = source.Height, 
        TotalBoxes = source.TotalBoxes, 
        Price = source.Price 
WHEN NOT MATCHED THEN  
     INSERT (ShippingID,Weight,Height,TotalBoxes,Price) 
     VALUES (source.ShippingID,source.Weight,source.Height,source.TotalBoxes,source.Price); 
+0

他將自己的問題標記爲「Sql Server 2005」,因此我相信爲什麼MERGE(upsert)不適合他。 – granadaCoder 2013-03-19 18:45:39

+0

啊,悲傷。 K. – 2013-03-19 18:47:17