【发布时间】:2014-03-04 21:27:42
【问题描述】:
我的表格有两列:Amount 和 Date
当我添加新值时,如果已经有该日期的记录,我想更新金额。如果没有,我只想插入我的新值。
【问题讨论】:
-
请提供您的表的
CREATE声明。
标签: sql sql-server-ce
我的表格有两列:Amount 和 Date
当我添加新值时,如果已经有该日期的记录,我想更新金额。如果没有,我只想插入我的新值。
【问题讨论】:
CREATE声明。
标签: sql sql-server-ce
假设您至少有 SQL Server 2008,您可以使用 MERGE 关键字。这个关键字是专门为像你这样的情况添加的。您指定一个 MERGE 子句(基本上是一个连接),然后使用语句告诉它在找到匹配项或未找到匹配项时如何处理。
底部有一个不错的示例,显示了目标表和由单行参数创建的源“表”之间的合并。稍微简化一下,你可以使用类似的东西:
MERGE [TargetTable] AS target -- This is the table we'll be updating
USING (SELECT @Date) AS source (Date) -- These are the new values
ON (target.Date = source.Date) -- Here we define how we find a "match"
WHEN MATCHED THEN -- If the date already exists:
UPDATE SET Amount = @Amount
WHEN NOT MATCHED THEN -- If the date does not already exist:
INSERT (Date, Amount) VALUES (@Date, Amount)
请注意,嵌套的 UPDATE 和 INSERT 子句不指定表。这是因为我们在定义目标表(MERGE 关键字之后指定的表)时已经告诉 SQL Server 对哪个表执行这些操作。
更新:此功能显然是由 SQL Server CE 提供的not supported,因此它不适用于您的特定情况。我将这个答案留在这里,因为它可能会帮助其他尝试在完整版 SQL Server 中做类似事情的人。 有关 SQL Server CE 解决方案,请查看BJury's 答案。
【讨论】:
作为IF .. NOT EXISTS 的替代方案,您可以断言更新,然后退回到插入。如果数据通常已经存在,这通常是一个相当高效的UPSERT 模式。
UPDATE MyTable
SET Amount = @NewAmount
WHERE Date = @Date;
IF @@ROWCOUNT = 0
INSERT INTO MyTable(Amount, Date) VALUES (@NewAmount, @Date);
【讨论】:
如果您使用的是 nhibernate ORM,那么您可以使用 SaveOrUpdate 会话方法。
【讨论】:
类似:
if exists(select * from table where date = @date)
update table set amount = @amount where date = @date
else
insert table (amount, date) select @amount, date
【讨论】: