Sql 对Insert语句中的每条记录使用函数的唯一ID

Sql 对Insert语句中的每条记录使用函数的唯一ID,sql,sql-server,Sql,Sql Server,我在存储过程中有一个语句 INSERT into table(ID, name, age) SELECT fnGetLowestFreeID(), name, age FROM @tempdata 函数fnGetLowestFreeID获取表的最低空闲ID。 我想为表中的每条记录插入唯一的ID。我尝试了迭代和事务。但它们并不适合这种情况 我不能使用标识列。我有使用0-4之间的ID和使用该函数分配最低自由ID的限制。如果返回的ID大于4,则函数返回错误。假设表中已经有1和2。函

我在存储过程中有一个语句

INSERT into table(ID, name, age)
    SELECT fnGetLowestFreeID(), name, age 
    FROM @tempdata
函数fnGetLowestFreeID获取表的最低空闲ID。 我想为表中的每条记录插入唯一的ID。我尝试了迭代和事务。但它们并不适合这种情况


我不能使用标识列。我有使用0-4之间的ID和使用该函数分配最低自由ID的限制。如果返回的ID大于4,则函数返回错误。假设表中已经有1和2。函数将返回0,我必须根据@tempdata中的记录数将此ID分配给新记录,将3分配给下一个记录,依此类推。

试试这个

CREATE TABLE dbo.Tmp_City(Id int NOT NULL IDENTITY(1, 1), 
Name varchar(50) , Country varchar(50), )

创建序列并将Sequence.NEXTVAL指定为ID
在insert语句中,您可以使用row_number之类的秩函数并执行类似操作

 INSERT into table(ID, name, age)
 SELECT row_number() over (order by id) + fnGetLowestFreeID(), name, age 
 FROM @tempdata
这里有3个场景-

1显示您正在使用的功能

2使用函数并使其唯一是没有意义的 仍然可以使用rank-

INSERT into table(ID, name, age)
 SELECT row_number() over (order by id) + fnGetLowestFreeID(), name, age 
 FROM @tempdata

3否则,去掉函数并使用maxid+1,因为您不想使用identiy列

您可以使用数字表来加入执行插入的查询。你可以用谷歌搜索这个概念来获取更多的信息,但本质上你可以创建一个表,比如一个带有某个整数类型的单列nums的名称数字,然后你可以添加一些行,从0或1开始,按你的需要添加。例如,您可以以以下表格内容结束:

nums
----
 0
 1
 2
 3
 4
 5
 6
然后您可以使用这样的表来修改插入,您不再需要该函数:

INSERT into table(ID, name, age)
SELECT t2.nums, t.name, t.age 
FROM (
    SELECT name, age, row_number() over (order by name) as seq
    FROM @tempdata
) t
INNER JOIN (
    SELECT n.nums, row_number() over (order by n.nums) as seq
    FROM Numbers n
    WHERE n.nums < 5 AND NOT EXISTS (
        SELECT * FROM table WHERE table.ID = n.nums
    )
) t2 ON t.seq = t2.seq
现在,这个查询省略了您的一个需求,即在没有可用插槽时启动错误,但这很容易修复。如果表中记录的计数加上@tempdata中记录的总和大于5,则可以执行前面的查询和测试。如果是这样,您将启动错误,因为您知道@tempdata中的记录没有足够的可用插槽


旁注:对于一个表来说,table看起来像是一个糟糕的名字,我希望在你的真实代码中你有一个有意义的名字:

你想要NEWID函数??ID的字段类型是什么?你可以使用Sequences。通常使用identity字段是创建唯一ID号的最简单方法。我猜,因为你说最低的自由ID是一个int,因此,您可以将FNGETLOWSTFREID替换为:select isnullmaxid+1,1 from table第二个无效TSQL。我无法使用标识列。我有使用0-4之间的ID和使用该函数分配最低自由ID的限制。如果返回的ID大于4,则函数返回错误。假设表中已经有1和2。函数将返回0,我必须根据@tempdata中的记录数将此ID分配给新记录,将3分配给下一条记录,依此类推。@AnkitaMogha,您应该在答案中输入它。
INSERT into table(ID, name, age)
SELECT t2.nums, t.name, t.age 
FROM (
    SELECT name, age, row_number() over (order by name) as seq
    FROM @tempdata
) t
INNER JOIN (
    SELECT n.nums, row_number() over (order by n.nums) as seq
    FROM Numbers n
    WHERE n.nums < 5 AND NOT EXISTS (
        SELECT * FROM table WHERE table.ID = n.nums
    )
) t2 ON t.seq = t2.seq