Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 数据库方案,自动增量_Sql Server - Fatal编程技术网

Sql server 数据库方案,自动增量

Sql server 数据库方案,自动增量,sql-server,Sql Server,这里是数据库问题。 是否可以对辅助ID或第三ID进行自动递增? 我需要做一些基于版本的东西,想象一下: ID Phrase PhraseID PhraseVersion 1 "" 1 1 2 "" 1 2 3 "" 1 3 4 "" 2 1 当添加到数据库中时,PhraseID可以是相同的数字。 如果PhraseID存在,我希望PhraseVersi

这里是数据库问题。 是否可以对辅助ID或第三ID进行自动递增? 我需要做一些基于版本的东西,想象一下:

ID  Phrase  PhraseID    PhraseVersion
1   ""      1           1
2   ""      1           2
3   ""      1           3
4   ""      2           1
当添加到数据库中时,PhraseID可以是相同的数字。 如果PhraseID存在,我希望PhraseVersion在数量上自动递增。 如果PhraseID不存在,我希望PhraseVersion重新开始,从1开始计算


I这可能吗?

我将使用PhraseVersion的计算列,该列将计算具有相同PhraseID和Id的行数,该行数低于或等于当前行数

为此,您需要创建一个UDF来计算短语版本:

CREATE FUNCTION dbo.GetPhraseVersion (
    @PhraseId int,
    @id int
)
RETURNS INT
AS
BEGIN
    RETURN (
        SELECT COUNT(*) 
        FROM T 
        WHERE PhraseId = @PhraseId 
        AND Id <= @id
    )
END
GO
现在进行测试-插入4条记录:

INSERT INTO T (PhraseId) VALUES(1),(1),(1),(2)
选择:

SELECT *
FROM T
结果:

id  PhraseId    PhraseVersion
1   1           1
2   1           2
3   1           3
4   2           1

这可以通过表上的插入触发器实现:

CREATE TABLE Phrases (
    ID INT IDENTITY(1,1) NOT NULL PRIMARY KEY, 
    PhraseID INT NOT NULL DEFAULT(0), 
    PhraseVersion INT NOT NULL DEFAULT(0))
GO

-- ==========================================================================================
-- Author:         Donna Landy
-- Create Date:    21 Nov 2019
-- Purpose:        To populate the PhraseVersion column (subordinate numeric key) on Insert
-- Note:           Must cater for >1 row being inserted when this trigger is called
-- Strategy:       Construct a temp table with the rows we need to consider, then update one row at a time
-- ==========================================================================================

CREATE TRIGGER Phrases_Insert ON Phrases AFTER INSERT
AS
BEGIN

    DECLARE @ID INT
    DECLARE @PhraseID INT
    DECLARE @PhraseVersion INT

    DECLARE @i INT
    DECLARE @iMax INT

    -- Create and populate temp table
    IF OBJECT_ID('tempdb..#phrases', 'U') IS NOT NULL DROP TABLE #phrases
    CREATE TABLE #phrases (i INT IDENTITY(1,1) PRIMARY KEY, ID INT, PhraseID INT)
    INSERT INTO #phrases (ID, PhraseID) SELECT ID, PhraseID FROM inserted

    -- Scan temp table
    SET @i=1
    SELECT @iMax=MAX(i) FROM #phrases

    WHILE @i <= @iMax BEGIN

        -- Fetch PhraseID & PhraseVersion for the row we are going to update
        SELECT @ID=ID, @PhraseID=PhraseID FROM #phrases WHERE i=@i

        -- Find the highest current Ref
        SELECT @PhraseVersion=ISNULL(MAX(PhraseVersion),0) FROM Phrases WHERE PhraseID=@PhraseID

        -- Update the row 
        UPDATE Phrases SET PhraseVersion=@PhraseVersion+1 WHERE ID=@ID 

        -- Increment loop counter
        SET @i+=1

    END

    -- Remove temp table
    IF OBJECT_ID('tempdb..#phrases', 'U') IS NOT NULL DROP TABLE #phrases

END
GO 

这对高频插入可靠吗?有可能有重复的短语ID-短语版本对吗?我不知道。首先,我不考虑你认为的高频率,其次,我从来没有用大量的数据来测试它。作为您的secpnd问题,这种情况不应该发生。@zoharpeld在计算列上应用筛选器时需要花费很多时间。@AGH我猜您指的是在where子句中使用计算列。不幸的是,由于此列基于UDF,因此无法将其标记为持久化,因此无法编制索引。我不知道您实施的具体情况,因此我无法进一步提供帮助。如果您有问题,欢迎随时发布适当的问题。@ZoharPeled此平台不允许我们重复问题。我也有同样的问题,并尝试你的回答评论了我的担忧。然而,这不是你们的错,因为提问者并没有在他的问题中提出这样的要求。
CREATE TABLE Phrases (
    ID INT IDENTITY(1,1) NOT NULL PRIMARY KEY, 
    PhraseID INT NOT NULL DEFAULT(0), 
    PhraseVersion INT NOT NULL DEFAULT(0))
GO

-- ==========================================================================================
-- Author:         Donna Landy
-- Create Date:    21 Nov 2019
-- Purpose:        To populate the PhraseVersion column (subordinate numeric key) on Insert
-- Note:           Must cater for >1 row being inserted when this trigger is called
-- Strategy:       Construct a temp table with the rows we need to consider, then update one row at a time
-- ==========================================================================================

CREATE TRIGGER Phrases_Insert ON Phrases AFTER INSERT
AS
BEGIN

    DECLARE @ID INT
    DECLARE @PhraseID INT
    DECLARE @PhraseVersion INT

    DECLARE @i INT
    DECLARE @iMax INT

    -- Create and populate temp table
    IF OBJECT_ID('tempdb..#phrases', 'U') IS NOT NULL DROP TABLE #phrases
    CREATE TABLE #phrases (i INT IDENTITY(1,1) PRIMARY KEY, ID INT, PhraseID INT)
    INSERT INTO #phrases (ID, PhraseID) SELECT ID, PhraseID FROM inserted

    -- Scan temp table
    SET @i=1
    SELECT @iMax=MAX(i) FROM #phrases

    WHILE @i <= @iMax BEGIN

        -- Fetch PhraseID & PhraseVersion for the row we are going to update
        SELECT @ID=ID, @PhraseID=PhraseID FROM #phrases WHERE i=@i

        -- Find the highest current Ref
        SELECT @PhraseVersion=ISNULL(MAX(PhraseVersion),0) FROM Phrases WHERE PhraseID=@PhraseID

        -- Update the row 
        UPDATE Phrases SET PhraseVersion=@PhraseVersion+1 WHERE ID=@ID 

        -- Increment loop counter
        SET @i+=1

    END

    -- Remove temp table
    IF OBJECT_ID('tempdb..#phrases', 'U') IS NOT NULL DROP TABLE #phrases

END
GO