【发布时间】:2022-01-15 21:20:33
【问题描述】:
我需要生成一个由任意前缀、年份和递增数字组成的代码。递增的数字必须在当年第一次生成数字时从 1 开始。
此代码需要添加到 sqlite 数据库并在 PHP 脚本的其他地方可用。
我现在所做的使用 4 次访问数据库:
$codePrefix = 'TEST';
$stmt = $db->prepare(
'INSERT INTO test (year)
VALUES(strftime("%Y", "now"))'
);
$stmt->execute();
$id = $db->lastInsertId();
$stmt = $db->prepare('SELECT `year` FROM `test` WHERE `id`=:id');
$stmt->bindValue(':id', $id);
$stmt->execute();
$result = $stmt->fetch(PDO::FETCH_ASSOC);
$year = $result['year'];
$stmt = $db->prepare('SELECT Ifnull(Max(id), 0) `max_id` FROM `test`
WHERE `year`<:year');
$stmt->bindValue(':year', $year);
$result = $stmt->execute();
$result = $stmt->fetch(PDO::FETCH_ASSOC);
$previousMax = $result['max_id'];
$codeSuffix = $id-$previousMax;
$code = "{$codePrefix}-{$year}-{$codeSuffix}";
$stmt = $db->prepare('UPDATE `test` SET `code`=:code WHERE `id`=:id');
$stmt->bindParam(':code', $code);
$stmt->bindParam(':id', $id);
$stmt->execute();
我在这里滥用id 是整数主键和自动增量的事实。
这行得通。但我觉得它正在以非常复杂的方式做一些非常简单的事情。
有没有更好的解决方案?我需要假设一月一日的午夜可能发生在代码的任何时刻,所以我不能在不访问数据库的情况下从 PHP 获取年份信息。
在有人问之前,即使没有绑定任何值,我也使用准备好的语句的原因是因为稍后显然会有更多的数据插入到表中。
【问题讨论】:
-
没有人会因为你总是使用准备好的语句而责备你!几乎每次我看到对没有间隙或带有前缀重复的顺序模式的要求时,它都是为了解决显示或输出问题,而不应该也不应该由数据库直接处理。今年数据库中的第一项只是查询的结果,它可以被称为
1,而无需存储它。所以在你仔细阅读这个之前,我真的会仔细检查你是否真的需要这个。 -
@ChrisHaas 我确定我需要它。代码实际上是我需要的,而不是需要代码来解决另一个问题。这与输出问题无关(我什至没有想到)。
-
@ChrisHaas 差距会让我心烦意乱,但如果它们很少存在,我会接受它们作为生活中的事实。在我实现它的方式中,只有在手动删除条目时才会出现差距。我绝对可以忍受。
-
你能做到
{$prefix}-{$year}-{$dayOfYear}-{$num}num是一个整数但不一定是连续的吗?即,只需使用 unix 时间戳,然后您就可以在插入时生成 id。 -
另请注意,如果您将下一条记录的 ID 基于最后一条记录的 SELECT 的结果,那么您将在运行多个线程时引入重复 ID 的可能性。