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

时间:2015-02-19 14:37:48

标签: sql firebird

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

1,2,3,4,5,6而不是1,2,4,6,10,1 ..

2 个答案:

答案 0 :(得分:3)

我创建了一个简单的例子来证明这一点:

CREATE TABLE renumber_example (
    id INTEGER NOT NULL
);

我用一些不连续的数字填充了这张表:

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语言的一部分,但它是Firebird的大多数SQL客户端的一部分(例如isql,flamerobin)。如果您使用客户端库(例如fbclient.dll,jaybird,Firebird .net提供程序等)直接从您自己的应用程序执行此操作,那么您必须省略SET TERM语句。

使用即将推出的Firebird 3(目前处于测试阶段),你也可以使用一个使用新ROW_NUMBER()窗口函数的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;

然而正如我之前在评论中提到的那样:请仔细考虑为什么要这样做,如果你真的需要。如果这些数字毫无意义,那么你就不应该关心这些差距,如果它们确实有意义,那么这些价值观在你的系统之外也有意义,在这种情况下重新编号会“打破”外部真相。此外,如果这些值是带有外键的主键或唯一键,则需要确保所有外键都为ON UPDATE CASCADE

答案 1 :(得分:1)

如果您要更新列位置,可以使用:

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