【问题标题】:SQL Server - self referencing constraintSQL Server - 自引用约束
【发布时间】:2011-02-10 12:53:06
【问题描述】:

使用 SQL Server 2008

我有一张包含股票/股票/证券信息的表格。此表包含可以拥有的股票。

每只股票都有与之相关的货币。问题是货币也是一种股票,它也可以被拥有。即持有现金时

create table Stock
(
StockId int identity(1,1) not null CONSTRAINT StockPK PRIMARY KEY,
stockName varchar(100),
...
CurrencyId CONSTRAINT StockCurrencyIDFK FOREIGN KEY REFERENCES Stock(StockID),
)

对于现金行,CurrencyId 将等于 StockId

我的问题是将货币数据放入表中。在插入时,如何使用 stockID 的标识值填充 CurrencyID 列?

【问题讨论】:

  • 是否通过存储的过程或触发器完成对该表的所有插入?如果我们摆脱 IDENTITY() 属性并自己实现 IDENTITY(),我们可以采取一些技巧,但您确实希望确保该代码只需要存在于一个地方。
  • 有没有理由不能在单独的表中使用货币?
  • 是的,所有插入都是通过存储过程完成的。
  • 它们需要在同一个表中,因为您可以同时持有股票和货币的头寸。仓位表有一个股票的关键

标签: sql-server foreign-keys identity self-reference


【解决方案1】:

首先,我认为CurrencyId后面一定有一个类型说明符(可能是int)。

继续您的问题,如果您坚持这样的设计,我认为插入自引用行可以在触发器的帮助下完成。只有 CurrencyId 应该允许 NULL,即 不要 将其定义为 NOT NULL (你的例子中没有,多么幸运)。这里有个问题:技术上应该允许空值,但逻辑上不允许空值,也就是说你必须总是在那里有一个值,否则触发器会为你填充它。 p>

顺便说一下,当我们谈论触发器时,这里有一个可能的实现:

CREATE TRIGGER Stock_UpdateCurrencyId
ON Stock
FOR INSERT, UPDATE
AS
UPDATE Stock
SET CurrencyId = StockId
FROM inserted
WHERE Stock.StockId = inserted.StockId
  AND inserted.CurrencyId IS NULL

所以,这个想法基本上是这样的:如果你插入一行空CurrencyId(或更新CurrencyId NULL),这意味着你希望该行引用自己(至少这是触发器会认为你想要的),否则你为 CurrencyId 指定正确的参考值,触发器会绕过这些行。

还记得我说过在逻辑设计中不应允许 NULL 吗?好吧,我这么说可能有点太仓促了。实际上,如果您只为 INSERT 定义触发器,您将能够存储 NULL,但只能在插入之后通过后续的 UPDATE 来存储。但我宁愿没有 NULL。

不管怎样,你还喜欢你的设计吗?

【讨论】:

  • 感谢您的意见。不幸的是 CurrencyID 不应该为空。我以一种有点老套的方式解决了这个问题,但对我有用。由于其他原因,我们必须在 stock 表中有一种未知货币。我通过禁用约束来设置它。当我们必须设置另一种货币时(很少发生),我将新货币的货币 ID 设置为未知,然后对货币 ID 运行更新以将其设置为他自己。
  • 好吧。当然,您应该从哪里知道得更多。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-04-19
  • 2015-09-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多