用于重新索引列的 Firebird SQL 命令

Firebird SQL command for reindexing a column

想知道 SQL 命令是什么来重新编号 firebird 中的列,所以该列的每一行都显示为:

1、2、3、4、5、6 而不是 1、2、4、6、10、11..

如果你想更新列位置,你可以使用这个:

ALTER TABLE tablename ALTER [COLUMN] colname POSITION <newpos>
<newpos>  ::=  an integer between 1 and the number of columns

http://www.firebirdsql.org/refdocs/langrefupd20-alter-table.html

我创建了一个简单的示例来演示这一点:

CREATE TABLE renumber_example (
    id INTEGER NOT NULL
);

我用一些不连续的数字填充了这个table:

INSERT INTO renumber_example (id) VALUES (1);
INSERT INTO renumber_example (id) VALUES (4);
INSERT INTO renumber_example (id) VALUES (5);
INSERT INTO renumber_example (id) VALUES (10);
INSERT INTO renumber_example (id) VALUES (15);

要重新编号,您可以使用 EXECUTE BLOCK 或存储过程:

SET TERM #;
EXECUTE BLOCK
AS
    DECLARE newId INTEGER;
BEGIN
    newId = 1;
    FOR select id from renumber_example order by id AS CURSOR reorder DO
    BEGIN
        UPDATE renumber_example SET id = :newId WHERE CURRENT OF reorder;
        newId = newId + 1;
    END
END#
SET TERM ;#

注意:SET TERM 实际上不是 Firebird SQL 语言的一部分,但它是大多数 SQL Firebird 客户端(例如 isql、flamerobin)的一部分。如果您使用客户端库(例如 fbclient.dll、jaybird、Firebird .net 提供商等)直接从您自己的应用程序执行此操作,那么您必须省略 SET TERM 语句。

对于即将推出的 Firebird 3(目前处于测试阶段),您还可以通过使用新 ROW_NUMBER() window 函数的单个 MERGE 语句来完成此操作:

MERGE INTO renumber_example as target
    USING (
        SELECT id, ROW_NUMBER() OVER(ORDER BY id) as newId 
        FROM renumber_example
    ) AS source
    ON target.id = source.id
    WHEN MATCHED THEN
        UPDATE SET target.id = source.newId;

然而,正如我之前在评论中提到的:请仔细考虑您为什么要这样做以及是否确实需要这样做。如果数字毫无意义,那么您不应该关心差距,如果它们确实有意义,那么这些值很可能在您的系统之外也有意义,在这种情况下重新编号 'breaks' 外部事实。此外,如果这些值是带有外键的主键或唯一键,那么您需要确保所有外键都是 ON UPDATE CASCADE.