2016-06-07 76 views
-1

是非常簡單的來解釋我想要做什麼,但我認爲是有點困難implment,以及...認爲是我在做一個存儲過程recives一個XML PARAM,然後Im做將插入件與在XML中的記錄進行選擇,事端是這樣的:插入選擇儘管一些記錄從選擇有錯誤

insert into @pedXMl 
SELECT distinct 
    LTRIM(RTRIM(nref.value('@COL_0','VARCHAR(50)'))) NumPedido, 
    LTRIM(RTRIM(nref.value('@COL_1','VARCHAR(50)'))) CodAlmacen 
    FROM @PI_ParamXML.nodes('/CARGAPEDIDO/REGISTRO') as R(nref) 
    WHERE LTRIM(nref.value('@COL_0','VARCHAR(50)')) <> '' 

的事情是,在我的XML正在添加像參數將是錯誤的記錄,我要的是保持插入ALTHOUGH記錄會引發錯誤。 對不起我英語不好我正在追求最好的,我希望你是不夠的,可以幫助這個!謝謝!

+0

嗨基於集合的方法,這是仍處於打開狀態?你需要進一步的幫助嗎?如果這個問題得到解決,那麼在最佳答案的投票櫃檯下面勾選驗收將會很好。這將1)標記這個問題已解決2)使追隨者更容易找到最佳的解決方案3)支付點給回答者和4)支付點給你。一旦你自己超過了15分的邊界,你又被要求對貢獻進行投票。這是SO的方式來說聲謝謝。快樂編碼! – Shnugo

回答

0

這取決於什麼是錯誤?

這可能是

  • 無效的XML(僅當您在XML作爲字符串傳遞,並在內部將其丟)
  • 無效的內部藥結構(節點/屬性丟失,損壞嵌套...)
  • 在石膏
  • 錯誤的值(應該是INT,但並不)
  • 遭破壞的商業規則(例如值不能爲1,如果其他值爲0)

無論如何:一個聲明是一個步驟。它將全部工作,否則將失敗。達到你想要什麼

一種方法是一行一行地辦法(CURSOR),第二個是用一個臨時表一組爲基礎的方法:

作爲一個例子,我認爲這是錯誤的值,但總的方法應該是完全一樣的其他問題:

第二個數據節點具有無效valueInt

DECLARE @passedIn XML= 
'<root> 
    <data rowID="1"> 
     <valueInt>111</valueInt> 
     <valueString>hello1</valueString> 
    </data> 
    <data rowID="2"> 
     <valueInt>222xyz</valueInt> 
     <valueString>hello2</valueString> 
    </data> 
    <data rowID="3"> 
     <valueInt>333</valueInt> 
     <valueString>hello3</valueString> 
    </data> 
</root>'; 

這是CURSOR方法

DECLARE @target TABLE(RowID INT,valueInt INT,valueString NVARCHAR(MAX)); 
DECLARE @errors TABLE(rowID INT,DataNode XML); 

DECLARE @rowID INT; 
DECLARE @vInt NVARCHAR(MAX); --type is NVARCHAR!!! 
DECLARE @vString NVARCHAR(MAX); 
DECLARE @DataNode XML; 

DECLARE cur CURSOR FOR 
(
    SELECT data.value('@rowID','int') AS RowID 
      ,data.value('valueInt[1]','nvarchar(max)') AS ValueInt --type is NVARCHAR!!! 
      ,data.value('valueString[1]','nvarchar(max)') AS ValueString 
      ,data.query('.') AS DataNode 
    FROM @passedIn.nodes('/root/data') AS A(data) 
); 
OPEN cur; 
FETCH NEXT FROM cur INTO @rowID,@vInt,@vString,@DataNode; 
WHILE @@FETCH_STATUS=0 
BEGIN 
    BEGIN TRY 
     INSERT INTO @target VALUES(@rowID,@vInt,@vString); 
    END TRY 
    BEGIN CATCH 
     INSERT INTO @errors VALUES(@rowID,@DataNode); 
    END CATCH 
    FETCH NEXT FROM cur INTO @rowID,@vInt,@vString,@DataNode; 
END 
CLOSE cur; 
DEALLOCATE cur; 

--This is the result 
SELECT * FROM @target; 
SELECT * FROM @errors; 

清理並重新開始通過臨時表

DELETE FROM @target; 
DELETE FROM @errors; 

SELECT data.value('@rowID','int') AS RowID 
     ,data.value('valueInt[1]','nvarchar(max)') AS ValueInt --type is NVARCHAR!!! 
     ,data.value('valueString[1]','nvarchar(max)') AS ValueString 
     ,data.query('.') AS DataNode 
INTO #stagingTable 
FROM @passedIn.nodes('/root/data') AS A(data); 

INSERT INTO @target 
SELECT RowID,ValueInt,ValueString 
FROM #stagingTable 
WHERE ISNUMERIC(ValueInt)=1; 

INSERT INTO @errors 
SELECT RowID,DataNode 
FROM #stagingTable 
WHERE ISNUMERIC(ValueInt)=0; 

SELECT * FROM @target; 
SELECT * FROM @errors; 

GO 
DROP TABLE #stagingTable; 
+0

我曾考慮過這樣做,但是,我有這麼多的記錄,我認爲這可能會影響表現,不是嗎? –

+0

@ C.Lopez是的,沒有任何疑問......如果您無法確定您的數據質量,那麼您必須付出額外的努力。其他類型的CAST價格昂貴。如果您必須以字符串的形式檢索數據以便在投射之前首先檢查它們,則必須執行兩次......您沒有解釋您期望的錯誤類型。你也沒有提到你的SQL Server的版本。從SS2012開始,您可能會閱讀['TRY_CAST','TRY_CONVERT'和'TRY_PARSE'](https://msdn.microsoft.com/zh-cn/library/hh974669.aspx) – Shnugo