【问题标题】:PHP: Writing unique random number to databasePHP:将唯一随机数写入数据库
【发布时间】:2016-11-12 16:30:55
【问题描述】:

我正在尝试将串行和随机 PIN 写入 mysql 数据库,但某些 PIN 值被多次写入。

如果 $pin 已经存在,我如何跳过将其写入 pin 列?

sn-p 如下:

<?php

for($serial = 1000; $serial <= 1600; $serial++) {
    $serial_prefix = "HCIS";

    //generate random figures.
    $rand_pin1 = rand(10599, 99999);
    $rand_pin2 = rand(22222, 89898);
    $pin = $rand_pin1 . $rand_pin2;
    $f_serial = $serial_prefix . $serial;

    $check = "SELECT pin FROM pin_serial WHERE pin = '$pin'";
    $check_query = mysqli_query($connection, $check);
    if(mysqli_num_rows($check_query) > 0){
        // how do I skip writing $pin into pin column if it already exist here

    } 
    elseif(mysqli_num_rows($check_query) == 0){
        //inserting a generated figure and $serial into serial and pin column.
        $pin_serial_query = "INSERT INTO pin_serial (serial, pin) VALUES('$f_serial', '$pin')";
        mysqli_query($connection, $pin_serial_query);
    }
}

【问题讨论】:

    标签: php mysql database random


    【解决方案1】:

    do..while 循环应该可以解决您的问题:

    for ( $serial = 1000; $serial <= 1600; $serial++ ) {
    
      $serial_prefix = "HCIS";
    
      do {
    
        // generate random figures
        $rand_pin1 = rand( 10599, 99999 );
        $rand_pin2 = rand( 22222, 89898 );
        $pin = $rand_pin1 . $rand_pin2;
        $f_serial = $serial_prefix . $pin;
    
        $check = "SELECT pin FROM pin_serial WHERE pin = '$pin'";
        $check_query = mysqli_query( $connection, $check );
    
      } while ( mysqli_num_rows( $check_query ) >0 );
    
      //inserting a generated figure and $serial into serial and pin column.
      $pin_serial_query = "INSERT INTO pin_serial ( serial, pin ) VALUES ( '$f_serial', '$pin' )";
      mysqli_query( $connection, $pin_serial_query );
    
    }
    

    虽然这将解决您的直接问题,但随着行数的增加,您最终会发送越来越多的 SQL 请求,直到您找到未使用的 PIN。如果您允许 mySQL 为每个新行生成唯一的 PIN,您可能会对结果更满意。

    【讨论】:

    • 当我尝试您的解决方案时,几乎所有引脚值都相同。它对我不起作用。我做错了什么?
    • 对不起......我犯了愚蠢的错误。更改“$f_serial = $serial_prefix . $serial;”到“$f_serial = $serial_prefix . $pin;”它会起作用。我已经在答案中更正了这一点。
    • 太棒了!很高兴我能帮上忙。
    【解决方案2】:

    pin 列创建唯一索引:

    ALTER TABLE `pin_serial` ADD UNIQUE INDEX (`pin`)
    

    然后将您的查询更改为

    INSERT INTO pin_serial (serial, pin) VALUES('$f_serial', '$pin')
        ON DUPLICATE KEY UPDATE serial_pin = VALUES(serial_pin)
    

    (注意ON DUPLICATE KEY UPDATE serial_pin = VALUES(serial_pin) 部分,这只是示例,您可以直接 pin=pin 跳过)如果具有该 pin 值的行已经存在,它将更新查询,或者插入新行。

    您也可以使用INSERT IGNORE 语句,它会忽略重复项。

    More about INSERT in MySQL docs 主题

    请注意,在您的示例中,脚本容易受到 Sql injection 攻击。为避免这种情况,您应该首先将参数传递给mysqli_real_escape_string 函数,以使内部的数据安全(通过转义不明确的字符)

    【讨论】:

    • 好主意,但我会添加一个关于 SQL 注入风险 的警告(即使它似乎是 Pi/arduino 本地代码)
    • @Blag 好点,在答案中添加了关于 sql 注入的注释。
    • pin 和 serial 列已经是唯一键。我尝试了您提供的解决方案,但仍然写了多个 pin。
    • @user3186314 你有unique index(pin, serial_pin)吗?那么你必须有unique pair,也就是说,只有插入现有的serial和serial_pin组合才会出错。您需要更改为拥有两个唯一索引。
    • 引脚和序列号是唯一的。当我在 pin 列中看到重复项时,我感到很惊讶。
    【解决方案3】:

    如果您想将序列写入 pin 生成 pin 所在的行(有效地覆盖已经存在的旧序列,您可以使用 UPDATE 语句:

    ... "UPDATE pin_serial SET serial='$serial'";
    

    如果您只想跳过此引脚/串行组合,我想您已经得到了答案。您的代码应该可以工作

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-02
      • 2016-06-24
      • 2013-07-27
      • 2013-05-29
      • 1970-01-01
      • 2011-06-14
      相关资源
      最近更新 更多