插入选择虽然选择中的某些记录有错误

时间:2016-06-07 20:48:30

标签: sql sql-server xml tsql

解释我想要做什么很简单,但我认为有点难以实现,好吧......我认为我正在做一个存储过程来重现XML参数,然后我做了一个插入选择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 comming like参数中会有错误的记录,我想要的是继续插入记录抛出错误。 对不起,我的英语不好我是最好的,我希望你能受到影响并且可以帮忙解决这个问题!谢谢!

1 个答案:

答案 0 :(得分:0)

这取决于什么是错误?

这可能是

  • 无效的XML(仅当您将XML作为字符串传递并在内部投射时)
  • 内部结构无效(节点/属性缺失,嵌套错误......)
  • 演员表中的错误值(应为INT,但不是
  • 业务规则损坏(例如,如果其他值为0,则值不能为1)

无论如何:一个声明是一步。它将完全起作用或失败。

实现目标的一种方法是逐行方法(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;