简体   繁体   English

T-SQL游标和更新

[英]T-SQL cursor and update

I use a cursor to iterate through quite a big table. 我使用游标遍历一个很大的表。 For each row I check if value from one column exists in other. 对于每一行,我检查一列中的值是否存在于另一列中。

If the value exists, I would like to increase value column in that other table. 如果值存在,我想增加该其他表中的value列。 If not, I would like to insert there new row with value set to 1. 如果没有,我想在那里插入新行,并将其值设置为1。

I check "if exists" by: 我通过以下方式检查“是否存在”:

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

I don't know how to get that row which was found and update value. 我不知道如何获取找到的行并更新值。 I don't want to make another select. 我不想再次选择。

How can I do this efficiently? 我如何有效地做到这一点?

I assume that the method of checking described above isn't good for this case. 我认为上述检查方法不适用于这种情况。

Depending on the size of your data and the actual condition, you have two basic approaches: 根据数据的大小和实际情况,您有两种基本方法:

1) use MERGE 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 (...);

the TOP is needed because when you're doing a huge update like this (you mention the table is 'big', big is relative, but lets assume truly big, +100MM rows) you have to batch the updates, otherwise you'll overwhelm the transaction log with one single gigantic transaction. 之所以需要TOP是因为当您进行如此大的更新(您提到表是'big',big是相对的,但是假设真正的大,+ 100MM行)时,您必须分批进行更新,否则您将一个巨大的事务使事务日志不堪重负。

2) use a cursor, as you are trying. 2)尝试使用游标。 Your original question can be easily solved, simply always update and then check the count of rows updated: 您最初的问题可以轻松解决,只需始终进行更新,然后检查更新的行数即可:

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

Note that this approach is dangerous though because of race conditions: there is nothing to prevent another thread from inserting the value concurrently, so you may end up with either duplicates or a constraint violation error (preferably the latter...). 请注意,由于竞争条件,该方法很危险:没有什么可以阻止另一个线程同时插入值,因此您可能会遇到重复或约束违反错误(最好是后者...)。

This is just psuedo code because I have no idea of your table structure but I think you will understand... basically Update the columns you want then Insert the columns you need. 这只是伪代码,因为我不了解您的表结构,但我想您会了解...基本上,更新所需的列,然后插入所需的列。 A Cursor operation sounds unnecessary. 听起来不需要进行游标操作。

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

Without a sample, I think this is the best I can do. 没有样本,我认为这是我能做的最好的事情。 Bottom line: you don't need a cursor. 底线:您不需要光标。 UPDATE where a match exists ( INNER JOIN ) and INSERT where one does not. 存在匹配项时UPDATEINNER 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)

I think you'd be better off using a view for this -- then it's always up to date, no risk of mistakenly double/triple/etc counting: 我认为您最好使用一种视图 -然后它始终是最新的,没有错误地将double / triple / etc计数的风险:

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

But if you still want to use the INSERT/UPDATE approach: 但是,如果您仍然想使用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

What about Update statement with inner join to perform +1, and Insert selected rows that do not exist in the first table. 带有内部联接的Update语句如何执行+1,然后插入第一个表中不存在的选定行。

Provide the tables schema and the columns you want to check and update so I can help. 提供您要检查和更新的表架构和列,以便为您提供帮助。

Regards. 问候。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM