想象一下Price
表格中有一个Products
列,价格可能会发生变化。
我对它的改动很好但是我想将原始的Price
值存储在另一列中。
MS SQL服务器可以自动执行此操作吗?
我可以使用默认值字段执行此操作吗?
我必须申报一个触发器吗?
我尝试使用Price
来简化问题,但看起来这样会激起“使用单独表格”类型的答案。
对于我造成的困惑,我感到很遗憾。
在现实世界中,我需要存储一个外键ID,我是100%我只需要当前和原始值
我对所提出的不同方法感到有些困惑,所以请让我再次解释一下情况。
虚构Products
表有三个字段:ID
,Price
和OriginalPrice
。
我想在任何插入上设置OriginalPrice
到Price
值。
有时它是从代码创建的单个产品。有时候,存储过程中有一千个由insert
创建的产品,所以我也想正确处理这些产品。
设置OriginalPrice
后,我从不打算更新它。
希望我的问题现在更清楚了 谢谢你的努力。
我要感谢所有人,特别是@gbn,感谢他们的帮助 虽然我发布了my own answer,但它主要基于@gbn's answer以及他的进一步建议。他的答案也更完整,因此我将其标记为正确。
答案 0 :(得分:3)
更新后,我们假设您只有旧值和新值。
如果由于客户端代码错误导致相同的更新快速连续发生并且您对历史不感兴趣(其他答案),请忽略
您可以使用触发器或存储过程。
就个人而言,我会使用存储过程来提供基本的控制。然后不需要直接的UPDATE权限,这意味着除非通过您的代码,否则只读。
CREATE PROC etc
...
UPDATE
MyTable
SET
OldPrice = Price,
Price = @NewPrice,
UpdatedBy = (variable or default)
UpdatedWhen = DEFAULT --you have a DEFAULT right?
WHERE
PKCol = @SomeID
AND --provide some modicum of logic to trap useless updates
Price <> @NewPrice;
触发器类似,但您需要与INSERTED和DELETED表进行JOIN 如果有人直接更新OldPrice怎么办?
UPDATE
T
SET
OldPrice = D.Price
FROM
Mytable T
JOIN
INSERTED I ON T.PKCol = I.PKCol
JOIN
DELETED D ON T.PKCol = D.PKCol
WHERE
T.Price <> I.Price;
现在你明白为什么你会跳起来......?
问题编辑后,仅 INSERT
UPDATE
T
SET
OriginalPrice = I.Price
FROM
Mytable T
JOIN
INSERTED I ON T.PKCol = I.PKCol
但是如果所有INSERT都是通过存储过程发生的话我会把它设置在那里......
答案 1 :(得分:2)
SQL Server表列没有readonly属性。但是您可以使用触发器(和限制权限)来实现您描述的功能
除外,它不是解决问题的最佳方法。而是将价格视为类型2 'slowly changing dimension'.这涉及具有'ValidTo'列(os'StartDate'和'EndDate'列),并关闭记录:
Supplier_Key Supplier_Code Supplier_Name Supplier_State Start_Date End_Date
123 ABC Acme Supply Co CA 01-Jan-2000 21-Dec-2004
124 ABC Acme Supply Co IL 22-Dec-2004
如果您确实使用了触发器的路径(我建议您使用SCD类型2),请确保它可以处理多行:Multirow Considerations for DML Triggers
答案 2 :(得分:1)
我建议您将价格存储在名为Prices
的单独表格中,其中包含Price
和Date
列。
然后,只要价格更新,INSERT
就会有Prices
表中的新记录。然后当你需要知道当前的价格时,你可以从那里开始。
但是,如果您希望自动更新OriginalPrice
列,可以在表格中添加TRIGGER
来执行此操作:
http://msdn.microsoft.com/en-us/library/aa258254%28v=sql.80%29.aspx
答案 3 :(得分:0)
这是我最终得到的结果,得到了@gbn,@Mitch和@Curt的大力帮助:
create trigger TRG_Products_Price_I --common-ish naming style
on dbo.Products after insert as
begin
set nocount on
update m
set OriginalPrice = i.Price
from Products p
join inserted i on p.ID = i.ID
end
我也试图关注this article 谢谢大家!