我想在特定位置的SQL服务器表中插入一行。例如,我的表有100行,我想在第9位插入一个新行。但是,作为表的PK的ID列已经有一个ID为9的行。如何在此位置插入一行以便所有它转移到下一个位置后的行?
答案 0 :(得分:10)
关系表没有“位置”。作为优化,索引将按指定键对行进行排序,如果您希望在键顺序中的特定排名处插入行,请使用在该排名位置排序的键插入该行。在您的情况下,如果ID大于8,则必须使用值更新所有行,以使ID增加1,然后插入值为9的ID:
UPDATE TABLE table SET ID += 1 WHERE ID >= 9;
INSERT INTO TABLE (ID, ...) VALUES (9, ...);
毋庸置疑,做出类似的事情可能没有任何明智的理由。如果您真的有这样的要求,那么您将使用具有两个(或更多)部分的复合键。这样的键允许您插入子键,以便按所需顺序排序。但更有可能的是,你的问题可以通过指定正确的ORDER BY来解决,而不会弄乱行的物理顺序。
另一种看待它的方法是重新考虑主键的含义:实体的标识符,在该实体生命周期内不会发生变化。那么你的问题可以用一种让问题中的谬误更明显的方式来改写:
我想将ID为9的实体的内容更改为新的内容 值。应将实体9的旧值移动到内容中 ID为10的实体。具有ID 10的实体的旧内容应该是 移动到ID为11的实体......依此类推。老人 具有最高ID的实体的内容应作为新插入 实体。
答案 1 :(得分:4)
不,您无法控制新行的插入位置。实际上,您不需要:使用ORDER BY
语句中的SELECT
子句以您需要的方式对结果进行排序。
答案 2 :(得分:3)
通常你不想以这种方式使用主键。 更好的方法将创建另一个名为“position”或类似的列,您可以跟踪自己的订购系统。
要执行转换,您可以运行如下查询:
UPDATE table SET id = id + 1 WHERE id >= 9
如果您的列使用auto_increment功能,则无效。
答案 3 :(得分:2)
DECLARE @duplicateTable4 TABLE (id int,data VARCHAR(20))
INSERT INTO @duplicateTable4 VALUES (1,'not duplicate row')
INSERT INTO @duplicateTable4 VALUES (2,'duplicate row')
INSERT INTO @duplicateTable4 VALUES (3,'duplicate rows')
INSERT INTO @duplicateTable4 VALUES (4,'second duplicate row')
INSERT INTO @duplicateTable4 VALUES (5,'second duplicat rows')
DECLARE @duplicateTable5 TABLE (id int,data VARCHAR(20))
insert into @duplicateTable5 select *from @duplicateTable4
delete from @duplicateTable4
declare @i int , @cnt int
set @i=1
set @cnt=(select count(*) from @duplicateTable5)
while(@i<=@cnt)
begin
if @i=1
begin
insert into @duplicateTable4(id,data) select 11,'indian'
insert into @duplicateTable4(id,data) select id,data from @duplicateTable5 where id=@i
end
else
insert into @duplicateTable4(id,data) select id,data from @duplicateTable5 where id=@i
set @i=@i+1
end
select *from @duplicateTable4
答案 4 :(得分:0)
这种违反了关系表的目的,但如果你需要,那就不那么难了。
1)使用ROW_NUMBER() OVER(ORDER BY NameOfColumnToSort ASC) AS Row
为表格中的行号创建一列。
2)从这里,您可以使用{{1}将表的前后部分(使用SELECT columnsYouNeed INTO
)复制到两个单独的表中(基于您要在其后插入值的行号)分别和WHERE Row < ##
语句。
3)接下来,使用Row >= ##
删除原始表格。
4)然后使用DROP TABLE
作为before表,要插入的行(使用单个显式定义的UNION
语句,而不使用其他任何内容)和after表。到目前为止,您有3个单独的select子句的两个SELECT
语句。在这里,您可以将其包装在UNION
子句中,将其称为原始表的名称。
5)最后,你SELECT INTO FROM
你制作的两张桌子。
这类似于DROP TABLE
的工作方式。
答案 5 :(得分:0)
INSERT INTO customers
(customer_id, last_name, first_name)
SELECT employee_number AS customer_id, last_name, first_name
FROM employees
WHERE employee_number < 1003;