小编典典

SQL:检查插入是否成功(在一项任务中,从具有两列的表中获得8个不同的随机行)

sql

更新:

我解决了先前的问题。现在,代码已更新。结果是唯一的,ID是正确的。但是,新问题是:结果行的数量通常少于要求(8)。因为我添加CREATE UNIQUE INDEX topicid on rands (topicid);了拒绝在SQL层中重复插入的内容;循环-1,无论插入是否被拒绝。我现在正在寻找一种方法:如果成功插入THEN cnt- =
1。您知道在SQL层中执行此操作的任何方法吗?谢谢。


我有一个名为topictable的表,其中包含两个coulmns-
topicid和topic。我想从表中获得8个随机行而不重复。我从这里偷走了代码,并修改为获得两列结果。但是我有两个问题。1.没有区别;2.
ID错误(我以某种方式捕获了错误的随机ID)。

DELIMITER $$
DROP PROCEDURE IF EXISTS get_rands$$
CREATE PROCEDURE get_rands(IN cnt INT)
BEGIN
  DROP TEMPORARY TABLE IF EXISTS rands;
  CREATE TEMPORARY TABLE rands ( topicid INT ,topic VARCHAR(128) );
  CREATE UNIQUE INDEX topicid on rands (topicid);
loop_me: LOOP
    IF cnt < 1 THEN
      LEAVE loop_me;
    END IF; 
    INSERT INTO rands 
       SELECT topictable.topicid,topictable.topic
         FROM topictable 
         JOIN (SELECT (RAND()*(SELECT MAX(topictable.topicid) FROM topictable)) AS id) AS choices
        WHERE topictable.topicid >= choices.id
        LIMIT 1;
    SET cnt = cnt - 1;
  END LOOP loop_me;  
END$$
DELIMITER ;

我在php中使用以下函数来执行脚本。

    function pickrandomtopics($amountoftopics,$dbh){
try {  
    $randtable="CALL get_rands($amountoftopics)";
    $dbh->exec("$randtable");
    $topictemp = $dbh->query('SELECT * FROM rands');
    $topics = $topictemp->fetchAll(PDO::FETCH_ASSOC);
}  
catch(PDOException $e) {  
    echo $e->getMessage();  
}
return $topics;}

感谢您的帮助。


抱歉,我没有说清楚。此表中的所有主题在开始时都是唯一的。但是它们可能会在末尾重复,因为该函数会不时地随机选择行,有时它只将同一行选择两次。谢谢你的帮助。


阅读 209

收藏
2021-04-15

共1个答案

小编典典

感谢@tere拧ko。在CONTINUE HANDLER FOR SQLSTATE '23000'抓获“不是唯一的”错误和正确的+1 CNT回来。

DELIMITER $$
DROP PROCEDURE IF EXISTS get_rands$$
CREATE PROCEDURE get_rands(IN cnt INT)
BEGIN
  DECLARE CONTINUE HANDLER FOR SQLSTATE '23000' SET cnt = cnt + 1;
  DROP TEMPORARY TABLE IF EXISTS rands;
  CREATE TEMPORARY TABLE rands ( topicid INT UNIQUE,topic VARCHAR(128) );
loop_me: LOOP
    IF cnt < 1 THEN
      LEAVE loop_me;
    END IF; 
    INSERT INTO rands 
       SELECT topictable.topicid,topictable.topic
         FROM topictable 
         JOIN (SELECT (RAND()*(SELECT MAX(topictable.topicid) FROM topictable)) AS id) AS choices
        WHERE topictable.topicid >= choices.id
        LIMIT 1;
    SET cnt = cnt - 1;
  END LOOP loop_me;  
END$$
DELIMITER ;
2021-04-15