ziG*_*iGi 6 sql sql-server unique auto-increment
我有以下问题,我想要复合主键,如:
PRIMARY KEY (`base`, `id`);
Run Code Online (Sandbox Code Playgroud)
当我插入一个base基于前id一个相同的自动递增的id时base
例:
base id
A 1
A 2
B 1
C 1
Run Code Online (Sandbox Code Playgroud)
有没有办法,当我说:
INSERT INTO table(base) VALUES ('A')
插入一个新记录id3,因为这是base'A' 的下一个ID ?
结果表应该是:
base id
A 1
A 2
B 1
C 1
A 3
Run Code Online (Sandbox Code Playgroud)
是否有可能在数据库中完全执行它,因为如果以编程方式完成它可能会导致比赛条件.
编辑
在base目前代表公司,id代表发票号码.每家公司都应该有自动递增的发票编号,但可能会出现两家公司的发票编号相同的情况.使用公司登录的用户应该能够按这些发票号进行排序,过滤和搜索.
自从有人发布了类似的问题以来,我一直在思考这个问题。第一个问题是DB不提供“可分区”序列(该序列将基于不同的键重新启动/记住)。第二个是,SEQUENCE该对象是提供围绕快速访问减速,并且不能被回滚(即,你会得到间隙)。从本质上讲,这可以使用内置实用程序排除……这意味着我们必须自己动手。
我们首先需要的是一个表来存储我们的序列号。这可能非常简单:
CREATE TABLE Invoice_Sequence (base CHAR(1) PRIMARY KEY CLUSTERED,
invoiceNumber INTEGER);
Run Code Online (Sandbox Code Playgroud)
实际上,该base列应该是对定义您要为其开具发票的业务/实体的任何表/标识的外键引用。在此表中,您希望每个发布实体的条目都是唯一的。
接下来,您需要一个存储过程,该过程将带有一个键(base)并吐出序列(invoiceNumber)中的下一个数字。必要的密钥集会有所不同(即某些发票号必须包含发行的年份或完整日期),但是这种情况的基本格式如下:
CREATE PROCEDURE Next_Invoice_Number @baseKey CHAR(1),
@invoiceNumber INTEGER OUTPUT
AS MERGE INTO Invoice_Sequence Stored
USING (VALUES (@baseKey)) Incoming(base)
ON Incoming.base = Stored.base
WHEN MATCHED THEN UPDATE SET Stored.invoiceNumber = Stored.invoiceNumber + 1
WHEN NOT MATCHED BY TARGET THEN INSERT (base) VALUES(@baseKey)
OUTPUT INSERTED.invoiceNumber ;;
Run Code Online (Sandbox Code Playgroud)
注意:
没错,您在开具发票编号时仍然会阻止每笔业务。你不能避免这种情况,如果发票号必须是连续的,没有间隙-直到该行实际上是承诺,它可能会被回滚,这意味着发票号码就不会被发出。
现在,由于您不想记住调用该条目的过程,因此将其包装在触发器中:
CREATE TRIGGER Populate_Invoice_Number ON Invoice INSTEAD OF INSERT
AS
DECLARE @invoiceNumber INTEGER
BEGIN
EXEC Next_Invoice_Number Inserted.base, @invoiceNumber OUTPUT
INSERT INTO Invoice (base, invoiceNumber)
VALUES (Inserted.base, @invoiceNumber)
END
Run Code Online (Sandbox Code Playgroud)
(显然,您有更多的列,包括应自动填充的其他列-您需要填写它们)
...然后可以通过简单地说:
INSERT INTO Invoice (base) VALUES('A');
Run Code Online (Sandbox Code Playgroud)
那我们做了什么?通常,所有这些工作都是为了减少事务锁定的行数。在INSERT提交此内容之前,只有两行被锁定:
Invoice_Sequence维护序列号的行Invoice新发票所在的行。特定项目的所有其他行base都是免费的-可以随意更新或查询(从此类系统中删除信息会使会计师感到紧张)。您可能需要确定当查询通常包含待处理的发票时应该怎么办...
| 归档时间: |
|
| 查看次数: |
4175 次 |
| 最近记录: |