2010-10-28 35 views
1

我使用游标来遍历相当大的表。对于每一行我检查一列中的值是否存在于其他列中。T-SQL游标和更新

如果该值存在,我想增加另一个表中的值列。 如果没有,我想有插入新行设置为1

值我检查“是否存在”由:

IF (SELECT COUNT(*) FROM otherTabe WHERE... > 1) 
    BEGIN 
     ... 
    END 
ELSE 
    BEGIN 
     ... 
    END 

我不知道如何获取该行已被发现并更新值。我不想再做选择。

我该如何有效地做到这一点?

我假设上述检查方法对于这种情况不好。

+2

发布您的代码,以便我们可以建议您进行更新而不是游标的基于集合的方式。 – Brad 2010-10-28 20:00:18

回答

4

根据数据的大小和实际情况,你有两种基本方法:

1)使用MERGE

MERGE TOP (...) INTO table1 
USING table2 ON table1.column = table2.column 
WHEN MATCHED 
THEN UPDATE SET table1.counter += 1 
WHEN NOT MATCHED SOURCE 
THEN INSERT (...) VALUES (...); 

需要的TOP,因为当你做这样一个巨大的更新(你提到的表是“大”,大是相对的,但让我们假设真大, + 100MM行),你必须批量更新,否则你会用一个巨大的交易压倒交易日志。

2)使用游标,因为你正在尝试。你原来的问题就容易解决了,只需总是更新,然后检查更新的行数:

UPDATE table 
    SET column += 1 
WHERE ...; 
IF @@ROW_COUNT = 0 
BEGIN 
    -- no match, insert new value 
    INSERT INTO (...) VALUES (...); 
END 

请注意,这种做法是很危险的,但因为竞争条件:没有什么可以阻止另一个线程插入价值并发,所以你可能会最终重复或违反约束的错误(最好是后者...)。

1

如何使用内部联接更新语句执行+1,并插入第一个表中不存在的选定行。

提供表格模式和你想要检查和更新的列,所以我可以提供帮助。

问候。

+0

我发布了一些伪效果。 – Brad 2010-10-28 20:16:29

2

这只是psuedo代码,因为我不知道你的表结构,但我想你会明白...基本上更新你想要的列然后插入你需要的列。光标操作听起来没有必要。

Update OtherTable 
    Set ColumnToIncrease = ColumnToIncrease + 1 
FROM CurrentTable Where ColumnToCheckValue is not null 

Insert Into OtherTable (ColumnToIncrease, Field1, Field2,...) 
SELECT 
    1, 
    ? 
    ? 
FROM CurrentTable Where ColumnToCheckValue is not null 
+0

+1我应该发明x y表:) – 2010-10-28 20:06:16

2

没有样本,我认为这是我能做的最好的。底线:你不需要光标。 UPDATE其中存在匹配项(INNER JOIN)和INSERT,其中一项不存在。

UPDATE otherTable 
SET IncrementingColumn = IncrementingColumn + 1 
FROM thisTable INNER JOIN otherTable ON thisTable.ID = otherTable.ID 

INSERT INTO otherTable 
(
    ID 
    , IncrementingColumn 
) 
SELECT ID, 1 
FROM thisTable 
WHERE NOT EXISTS (SELECT * 
        FROM otherTable 
        WHERE thisTable.ID = otherTable.ID) 
2

我觉得you'd be better off using a view for this - 那么它总是最新的,没有错误的双/三/等计数的风险:

CREATE VIEW vw_value_count AS 
    SELECT st.value, 
     COUNT(*) AS numValue 
    FROM SOME_TABLE st 
GROUP BY st.value 

但是,如果你仍然想使用INSERT/UPDATE做法:

IF EXISTS(SELECT NULL 
      FROM SOMETABLE WHERE ... > 1) 
BEGIN 
    UPDATE TABLE 
     SET count = count + 1 
    WHERE value = @value 
END 
ELSE 
BEGIN 
    INSERT INTO TABLE 
    (value, count) 
    VALUES 
    (@value, 1) 
END