[英]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: 根据数据的大小和实际情况,您有两种基本方法:
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. 存在匹配项时
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)
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.