0

我有一个很大的表,里面有很多行,每一行都有每个用户在特定日子里的统计信息。显然我没有任何关于未来的统计数据。所以要更新我使用的统计数据

UPDATE Stats SET Visits=@val WHERE ... a lot of conditions ... AND Date=@Today

但是如果该行不存在怎么办?我不得不使用

INSERT INTO Stats (...) VALUES (Visits=@val, ..., Date=@Today)

如何检查该行是否存在?与执行 COUNT(*) 有什么不同吗?

如果我用空单元格填充表格,则需要数十万行占用兆字节并且不存储任何数据。

4

4 回答 4

2

如果您使用的是 SQL Server 2008 及更高版本,您还应该研究MERGE2008 版本中引入的语句。

于 2010-06-15T05:08:25.020 回答
1

我会尝试更新,然后如果 @@ROWCOUNT = 0 尝试插入

UPDATE Stats SET Visits=@val WHERE ... a lot of conditions ... AND Date=@Today
IF @@ROWCOUNT = 0
   INSERT INTO Stats (...) VALUES (Visits=@val, ..., Date=@Today)

或者尝试在 TRY/CATCH 中插入 INSERT,如果失败则更新。

我不会先测试

于 2010-06-15T04:47:59.373 回答
0

在这些情况下,我倾向于执行以下操作(伪代码,因为我自己是 DB2 人):

try:
    INSERT
catch already-exists:
    try:
        UPDATE
    catch anything:
        generate error

如果您更有可能拥有行,则可以按相反的顺序执行此操作:

try:
    UPDATE
catch not-there:
    try:
        INSERT
    catch anything:
        generate error

永远不会首先在 DBMS 中进行测试,因为数据库可能会在测试和执行之间发生变化(“请求宽恕而不是请求许可”原则)。

于 2010-06-15T04:48:54.520 回答
0

不幸的是,SQL Server 没有任何类型的“插入或更新”命令(我知道),就像一些数据库引擎一样。这意味着您必须首先检查该行或按照其他答案的建议捕获错误。希望您的行有一个人工主键,所以您可以首先使用所有 WHERE 条件查询该键,然后,如果返回一行,则执行UPDATE ... WHERE key = ...,否则执行 INSERT。这样你就不会运行整个查询两次。

于 2010-06-15T04:48:58.480 回答