我在存储过程中有一个声明
INSERT into table(ID, name, age)
SELECT fnGetLowestFreeID(), name, age
FROM @tempdata
函数fnGetLowestFreeID()
获得表table
的最低免费ID。
我想在表格中的每条记录中插入唯一ID。我尝试过迭代和事务。但它们不符合这种情况。
我无法使用Identity Column。我有这个限制,使用0-4之间的ID,并使用该功能分配最低的免费ID。如果返回的ID大于4,则该函数返回错误。假设表中已经有1和2。该函数将返回0,我必须将此ID分配给新记录,3分配给下一条记录,依此类推@Tempdata中的记录数。
答案 0 :(得分:0)
试试这个
CREATE TABLE dbo.Tmp_City(Id int NOT NULL IDENTITY(1, 1),
Name varchar(50) , Country varchar(50), )
OR
ALTER TABLE dbo.Tmp_City
MODIFY COLUMN Id int NOT NULL IDENTITY(1, 1)
OR
创建一个序列并将Sequence.NEXTVAL指定为ID 在插入声明中
答案 1 :(得分:0)
您可以使用像row_number这样的排名函数,并执行类似的操作。
INSERT into table(ID, name, age)
SELECT row_number() over (order by id) + fnGetLowestFreeID(), name, age
FROM @tempdata
答案 2 :(得分:0)
以下是3个场景 -
1)显示您正在使用的功能
2)使用函数并使其独特无意义 仍然 - 你可以使用排名 -
INSERT into table(ID, name, age)
SELECT row_number() over (order by id) + fnGetLowestFreeID(), name, age
FROM @tempdata
3)否则,摆脱功能并使用max(id)+1,因为你不想使用identitiy列
答案 3 :(得分:0)
您可以使用Numbers表来加入执行插入的查询。你可以谷歌这个概念获取更多信息,但基本上你创建一个表(例如名称"数字"),只有一个列" 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
现在,此查询省略了您的一个要求,即在没有可用的插槽时会启动错误,但这很容易修复。您可以先执行查询并测试table
中的记录数加上@tempdata
中的记录总数是否大于5.如果是,则启动错误,因为您知道不够@tempdata
中记录的空闲位置。
旁注:table
看起来像一张桌子的名字,我希望你的真实代码中有一个有意义的名字:)