我如何获得下一个开放号码?

时间:2014-12-22 23:10:23

标签: php mysql sql

我有一个看起来像这样的SQL列。

enter image description here

注意1100s和2000s中是否有数字(1101-1123没有显示,但它们存在)。我编写了一个脚本,以便注册某个组的用户将获得与该组相对应的登录信息。因此,如果他们在基本组中注册,他们将在1100年代首次登录。如果他们在温和的团体中注册,那么他们将在2000年代获得第一个可用的登录。假设用户AAL2002被删除,下一个加入的人应该登录2002而不是2007(以便自动填充空白)。

现在我有一个PHP脚本,它试图查看所有内容并为它们提供一个新的,未使用的登录。问题是它重复了一些登录。有没有其他方法可以用PHP和SQL做到这一点?

如果您认为可以修复,那么这是我可怕的,令人困惑的代码:

$husers = Query::runQuery("SELECT * FROM `users` WHERE `group`=? AND `login` NOT BETWEEN 'AAL1000' AND 'AAL1010'", array($post['group']));
            $i = 0;
            $f = false;
            do
            {
                $baseid = (substr($users[$i]['login'], 3)) + 1;

                if($baseid != substr($users[$i+1]['login'], 3))
                {
                    $checkid = Query::runQuery("SELECT * FROM `users` WHERE `login`=?", array("AAL".$baseid));

                    if($checkid[0]['login'] != "AAL".$baseid)
                    {
                        $f = true;
                    }

                }

                $i++;
            }

2 个答案:

答案 0 :(得分:0)

如果您有多个用户同时注册(竞争条件),则根本不起作用。您可以使用数据库事务解决此问题。 最重要的是,您应该使用SQL函数进行查找并为您的用户注册下一个免费ID。与事务一起,这将为您提供一个解决方案,即使您的脚本一次被多个人调用也能正常工作。

在mysql中,通常只使用和自动增加列来避免这种问题。在大多数其他数据库上,如果不使用连续整数列,则必须采取严格措施。

答案 1 :(得分:0)

鉴于:

CREATE TABLE login (
    login VARCHAR(4)
);

INSERT INTO login (login) 
    VALUES ('1100'), ('1101'), ('1102'), ('1106'), ('1107');

查询:

SELECT MIN(login) + 1 AS result FROM (
    SELECT login,
        (SELECT MIN(l2.login) FROM login l2 WHERE l2.login = l.login + 1) AS next
    FROM login l
    HAVING next IS NULL
) AS list;

给出以下结果:

+--------+
| result |
+--------+
|   1103 |
+--------+

我的示例仅使用alpha + decimal字段的整数部分。这使我无法进行substring operations,根据前缀(" AAL11"," AAL20")和最终的演员表(可能不会)进行分组我用varchar演示了必要但是仍然显示了可以完成的方式。我把它留作练习。

如前所述,您只能一起运行lookup + insert操作。这意味着您需要将此作为应用程序中的原子操作(通常称为事务,但我不是指SQL事务)。