【问题标题】:Insert into a row at specific position into SQL server table with PK使用 PK 将特定位置的行插入到 SQL Server 表中
【发布时间】:2011-10-21 05:30:30
【问题描述】:

我想在 SQL Server 表的特定位置插入一行。例如,我的表有 100 行,我想在位置 9 插入一个新行。但是表的 PK 的 ID 列已经有一个 ID 为 9 的行。我怎样才能在这个位置插入一行,以便所有移动到下一个位置后的行?

【问题讨论】:

    标签: sql sql-server insert rows


    【解决方案1】:

    不,您无法控制新行的插入位置。实际上,您不需要:在您的 SELECT 语句中使用 ORDER BY 子句以您需要的方式对结果进行排序。

    【讨论】:

      【解决方案2】:

      关系表没有“位置”。作为优化,索引将按指定键对行进行排序,如果您希望在键顺序中以特定排名插入行,请使用在该排名位置排序的键插入它。在您的情况下,如果 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 的实体的内容应作为新插入 实体。

      【讨论】:

        【解决方案3】:

        通常您希望以这种方式使用主键。 更好的方法 是创建另一个名为“位置”或类似的列,您可以在其中跟踪您自己的订购系统。

        要执行转换,您可以运行如下查询:

        UPDATE table SET id = id + 1 WHERE id >= 9

        如果您的列使用 auto_increment 功能,这将不起作用。

        【讨论】:

          【解决方案4】:

          这种方式违背了关系表的目的,但如果你需要,其实也不是那么难做到。

          1) 使用ROW_NUMBER() OVER(ORDER BY NameOfColumnToSort ASC) AS Row 为表格中的行号创建一列。

          2) 从这里您可以使用 WHERE Row < ## 和 @987654324 将表的前后部分复制(使用 SELECT columnsYouNeed INTO )到两个单独的表中(基于要在其后插入值的行号)分别@声明。

          3) 接下来使用DROP TABLE 删除原始表。

          4) 然后你使用UNION 用于前表、要插入的行(使用单个显式定义的SELECT 语句,没有其他任何内容)和后表。到目前为止,您有两个 UNION 语句用于 3 个单独的选择子句。在这里,您可以将其包装在 SELECT INTO FROM 子句中,将其称为原始表的名称。

          5) 最后,你 DROP TABLE 你制作的两张桌子。

          这类似于ALTER TABLE 的工作方式。

          【讨论】:

            【解决方案5】:
            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;
            

            更多参考:https://www.techonthenet.com/sql/insert.php

            【讨论】:

              【解决方案6】:
              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
              

              【讨论】:

              • 此代码可用于在特定位置插入值,在此我设置位置=1,其中新行值插入在行位置 1
              猜你喜欢
              • 2014-03-29
              • 2013-10-10
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2021-12-10
              • 1970-01-01
              • 2016-04-15
              • 1970-01-01
              相关资源
              最近更新 更多