更新表中的所有行与递增文本值

问题描述 投票:1回答:1

如何更新,每行的表使用SQL递增文本值的列。

我有一个名为叫ej_number列是一个唯一的标识符的表。字段格式为EJnnnn,即EJ其次是四位数字。我已经导入的数据不包括ej_number值,但一些新行做有它设置。我想不ej_number集更新的每一行,从EJ0001开始。我以后会解决重复。

我拳头做了它在PHP中的循环,但意识到,服务器将时间,因为行数的出来,所以我决定做它的SQL。

我的第一个想法是使用一个循环,但我的研究发现,不推荐使用的逐行更新,尤其是因为我可以看到这样做会使用游标,这也是不建议的唯一途径。

我能做到这一点在一条语句 - 以下作品的代码,但它会产生一个警告(使用MySQL工作台)。

SET @next_number = 0;
UPDATE ej_details
    SET ej_number = CASE
        WHEN ej_number IS NULL THEN (
            CONCAT('EJ', LPAD((@next_number:=@next_number+1), 4, '0')))
        ELSE ej_number
    END;

声明我想要做什么,但会产生这样的警告:

692行(S)的影响,1个警告:表达式中1287个设置用户变量已被弃用,将在以后的版本中删除。请设置在单独的报表变量来代替。行匹配:692更改:692个警告:1

我想知道如何更好地做到这一点,而无需使用弃用的功能。我看了一下,发现很多行由行的解决方案,但看不出是不是逐行,可能是因为我不知道足够问正确的问题的替代方法。

mysql sql loops
1个回答
0
投票

我觉得你只是想:

SET @next_number = 0;

UPDATE ej_details
    SET ej_number = CONCAT('EJ',
                           LPAD( (@next_number:=@next_number+1), 4, '0'
                               )
                          )
    WHERE ej_number IS NULL;

这是简单的,但不会改变错误。

如果你想这样做在一个单一的呼叫,那么:

UPDATE ej_details CROSS JOIN
       (SELECT @next_number := 0) params
    SET ej_number = CONCAT('EJ',
                           LPAD( (@next_number:=@next_number+1), 4, '0'
                               )
                          )
    WHERE ej_number IS NULL;

不幸的是,如果列被声明为unique,那么你可以不解决重复值“后”。

如果你想解决这个没有错误,你需要一个主键/唯一的列:

UPDATE ej_details ed JOIN
       (SELECT ed.*,
               ROW_NUMBER() OVER (ORDER BY ej_number) as seqnum
        FROM ej_details ed2
        WHERE ej_number IS NULL
       ) ed2
       ON ed2.? = ed.?  -- the primary key goes here
    SET ed.ej_number = CONCAT('EJ', LPAD(ed2.seqnum, 4, '0')
                             );

然而,这个版本是不向后兼容。

如果他们真的删除从MySQL 9.将打破很多,很多,很多的代码变量我会感到惊讶。

© www.soinside.com 2019 - 2024. All rights reserved.