我有一张桌子:
INSTRUCTIONS:
RecipeID
Step
...
RecipeID
由另一个系统生成。 RecipeID
不需要明确的外键关系。当我为特定配方插入Instructions
步骤时,我希望Step
增加。向新配方step
添加步骤时应该返回0,如下所示:
RecipeID | Step
---------------
0 | 0
0 | 1
RecipeID | Step
---------------
0 | 0
0 | 1
0 | 2
RecipeID | Step
---------------
0 | 0
0 | 1
0 | 2
1 | 0
我如何产生这种行为?
答案 0 :(得分:2)
不要这样做 你自己的问题表明这是一个糟糕的主意。 你怎么能有部分钥匙? 根据定义,部分密钥不能是唯一的。
从步骤中你唯一需要的是一个订单,显示它们(或者用Row_number查询它们)为0到n是微不足道的。
考虑一下你必须做什么,插入你错过的一个步骤,或交换它们......
RecipeStepID(作为代理主键)
RecipeID,StepNumber作为索引
表的任何外键链接都使用代理键
然后重新订购只是搞乱了StepNo
从未见过你试图不会变成灾难的事情,我可以算一下,如果没有把我的连指手机关掉,它就没有开始作为一场灾难。
答案 1 :(得分:0)
免责声明:请参阅底部的说明。我不一定建议使用触发器。
您可以使用instead of
触发器来更改将要插入的step
的值:
Create Trigger Instructions_UpdateSet
On [Instructions]
Instead of Insert
AS
BEGIN
insert instructions
select
i.recipe,
coalesce(ii.maxstep, -1)
+ row_number() over (partition by i.recipe order by i.step),
i.instruction
from inserted i
left join (select recipe, max(step) as maxstep from instructions group by recipe)
ii on i.recipe = ii.recipe
END;
这应该无缝地处理单个或多个记录的插入。如果您在单个查询中插入多个记录,则可以提供step
值以指示传入的插入记录的顺序,并且它们将被适当地排序并重新编号以在现有记录之后按顺序跟随。 / p>
演示:http://www.sqlfiddle.com/#!6/b13d5/1
在应用程序中使用触发器时需要注意的一些事项: