【问题标题】:How to increment number in T-SQL (not for auto-incremented key)?如何在 T-SQL 中增加数字(不适用于自动递增键)?
【发布时间】:2019-12-14 17:58:24
【问题描述】:

我有这张桌子

CREATE TABLE Dept 
(
    Deptno INT NOT NULL,
    Dname VARCHAR(50)  NOT NULL,
    Loc VARCHAR(50)  NOT NULL,

    CONSTRAINT Dept_PK PRIMARY KEY(Deptno)
);

如您所见,Deptno 不是自动递增的。

但我需要创建一个插入DnameLoc 的过程,其中Deptno 将自动生成。

到目前为止我所拥有的:

CREATE PROCEDURE InserNewDepartmentWithoutNumber
    @name VARCHAR(50),
    @location VARCHAR(50)
AS
    IF EXISTS(SELECT * FROM Dept WHERE Dept.Dname = @name)
        PRINT 'This department already exists'
    ELSE
    BEGIN
        INSERT INTO Dept (Dname, Loc)
        VALUES (@name, @location)       
    END

【问题讨论】:

  • 是什么阻止您简单地将列设为IDENTITY
  • @stickybit 数据库已完成,我想我不允许更改已创建的表。
  • 也许sequence 有用?
  • @HABO 你能用代码回答这个问题吗?
  • This 问题及其答案应该让您走上正确的道路。

标签: sql-server database tsql


【解决方案1】:

只需查找最后一个,最高的,使用的 Deptno 并添加一个。但是,我们确实需要小心确保如果此过程被同时调用多次,我们不会发出相同的新 Deptno。为了防止这种情况,我们使用事务,并暂时锁定Dept 表。

CREATE PROCEDURE InserNewDepartmentWithoutNumber
    @name VARCHAR(50),
    @location VARCHAR(50)
AS
BEGIN
    BEGIN TRANSACTION
        IF EXISTS(SELECT * FROM Dept WITH (UPDLOCK, HOLDLOCK) WHERE Dept.Dname = @name)
            PRINT 'This department already exists'
        ELSE
        BEGIN
            DECLARE @deptno INT
            SET @deptno = (SELECT MAX(Deptno) + 1 FROM Dept WITH (UPDLOCK, HOLDLOCK))
            INSERT INTO Dept (Deptno, Dname, Loc) VALUES (@deptno, @name, @location)    
        END
    COMMIT
END 

【讨论】:

  • 由于您不使用显式事务,因此如果多个用户同时运行 SP,您就有机会添加相同的号码。如果一个部门可以被删除,那么如果删除的部门具有最大DeptNo 值,您将重新发布一个部门号。
  • 是的。我已经添加了交易。重新发布的DeptNo 的问题可能会或可能不会对业务造成问题,但为了简单起见,除非另有说明,否则我会假设不会。
  • 您还需要将TabLockXHoldLock table hints 添加到select,否则仍然存在竞争条件,因为select 不会为交易的持续时间。
  • @ZoharPeled 虽然 SERIALIZABLE 将防止重复插入,但它会通过产生死锁来做到这一点,这有点令人不快。
  • @HABO TABLOCKX 过大(UPDLOCK,HOLDLOCK) 就足够了,正常情况下有索引不会锁定整个表。
猜你喜欢
  • 2016-04-22
  • 2020-01-15
  • 1970-01-01
  • 2014-12-07
  • 1970-01-01
  • 2016-03-07
  • 1970-01-01
  • 2015-11-03
  • 1970-01-01
相关资源
最近更新 更多