2

我有 2 张简单的桌子

+------|---------|----------+
+  ID  |  Value  |   Test   +
+------|---------|----------+
+  3   |   Test  |   12345  +
+  4   |  MyVal  |   56789  +
+  5   |  Another|   101010 +
+------|---------|----------+



+------|---------|----------+
+  ID  |  Value  |   Test   +
+------|---------|----------+
+  3   |   Test  |   12345  +
+  7   |  MyVal12|   56789  +
+  5   |  Another|   101010 +
+------|---------|----------+

ID两个表中的都是主键。

在我的存储过程中,我创建了一个像这样的临时表:

CREATE TABLE #tempTable(
        ID int NOT NULL PRIMARY KEY NONCLUSTERED,
        FIELD VARCHAR(255))

以及我的过程的一部分存储在try-catch块中:

BEGIN TRY
INSERT INTO #tempTable(ID, FIELD)
EXEC sp_executesql @myCustomSql, @paramList, @param1, @param2 ...
END TRY

BEGIN CATCH
      // what to put here ?
END CATCH

我想向我的临时表中添加行(您将看到 ID = 3 和 5 的重复项)并且我想继续添加。最后,我希望表格具有以下内容:

+------|---------+
+  ID  |  FIELD  +
+------|---------+
+  3   |   Test  +
+  4   |  MyVal  +
+  5   |  Another+ 
+  7   |  MyVal12+
+------|---------+

我在这里给出了一个简化的例子,在我的数据库中我有超过十万行和很多列。

谢谢

4

2 回答 2

3

要忽略(带有警告)尝试插入重复键而不是引发错误并使整个语句失败,您可以使用该IGNORE_DUP_KEY选项。

CREATE TABLE #tempTable
  (
     ID    INT NOT NULL PRIMARY KEY NONCLUSTERED WITH (IGNORE_DUP_KEY = ON),
     FIELD VARCHAR(255)
  ) 
于 2012-10-16T14:02:01.200 回答
0

你能不能只在两个表之间的@myCustomSQL 中加入一个 UNION 来过滤掉重复项?

如果不是,那么也许 GOTO 对你来说是最好的,

DECLARE @minID int;
SET @minID = 0;

-- Ensure your myCustomerSql only gets records with ID greater than @minID

:CarryOn

BEGIN TRY
INSERT INTO #tempTable(ID, FIELD)
EXEC sp_executesql @myCustomSql, @paramList, @param1, @param2 ...
END TRY

BEGIN CATCH
    IF ERROR_NUMBER() = 2627 -- Error code for duplicate key
    THEN
        SET @min_ID = SELECT MAX(ID) + 1 FROM #TempTable;
        GOTO CarryOn
    ELSE
        --Handle other errors somehow
END CATCH

我通常不会推荐任何像那样混乱的东西,但你显然已经有了脏数据,所以我希望这是一次修复它。

于 2012-10-16T13:45:52.963 回答