在 PHP 的预准备语句中设置 SQL 变量不起作用


Setting SQL variables in Prepared statments in PHP not working

>情况:我有一个连接表,其中包含列testFKquestionFKordinal

    testFK | questionFK | ordinal
       2         14          1
       2         15          2
       2         16          3
      _____________________________
 NEW   2         17          4

我想在表中添加一个新行,testFK = 2questionFK = 17,但是,我希望根据表中已有的内容自动生成ordinal。由于最高序数是 3,那么我希望SQL自动生成 4。

我试过:

$stmt = $db->prepare('
        SET @QOrdinal = (SELECT MAX(ordinal) FROM junc_test_question WHERE testFK = ?);
        INSERT 
        INTO junc_test_question
        (junc_test_question.testFK, junc_test_question.questionFK, junc_test_question.ordinal)
        VALUES (?, ?, @QOrdinal);
    ');

    $stmt->bind_param('iii', $this->testID, $this->testID, $question_id);
    //var_dump($stmt);
    if($stmt->execute()) {
        return true;
    } else {
        return false;
    }

如果我对ordinal进行硬编码,这就可以了,但我似乎无法SQL自己做

任何意见都非常感谢!

更新:我收到的错误

Fatal error:  Call to a member function bind_param() on a non-object in 'classes'Test.php on line 91

所以我假设SQL不正确。

在OP的最新评论中,下面提出的解决方案是不合适的。

如果您使用MyISAM

表类型并定义一个主键,其中自动增量列是第二个,那么MyISAM会自动计算按第一个字段分组的增量(请参阅链接文档中的MyISAM注释):

对于 MyISAM 表,您可以在辅助表上指定AUTO_INCREMENT 多列索引中的列。在这种情况下,生成的值 对于AUTO_INCREMENT列的计算公式为 MAX(auto_increment_column) + 1 其中前缀=给定前缀。这是 当您想将数据放入有序组中时很有用。

因此,您可以简单地按如下方式定义表-尽管在实践中,我不确定我是否会存储此序数:

DROP TABLE IF EXISTS my_table;
CREATE TABLE my_table
(testFK INT NOT NULL
,ordinal INT NOT NULL AUTO_INCREMENT
,questionFK INT NOT NULL
,PRIMARY KEY(testFK,ordinal)
) ENGINE = MYISAM;
INSERT INTO my_table VALUES
(2,1,14),          
(2,2,15),          
(2,3,16);
INSERT INTO my_table (testFK,questionFK) VALUES
(2,17);
SELECT * FROM my_table;
+--------+---------+------------+
| testFK | ordinal | questionFK |
+--------+---------+------------+
|      2 |       1 |         14 |
|      2 |       2 |         15 |
|      2 |       3 |         16 |
|      2 |       4 |         17 |
+--------+---------+------------+

或者,您可以按照以下思路做一些事情(简化) - 但我永远不会认真提倡这个解决方案:

INSERT INTO my_table (testFK,questionFK,ordinal) 
SELECT 2,18,MAX(ordinal+1) FROM my_table;
SELECT * FROM my_table;
+--------+---------+------------+
| testFK | ordinal | questionFK |
+--------+---------+------------+
|      2 |       1 |         14 |
|      2 |       2 |         15 |
|      2 |       3 |         16 |
|      2 |       4 |         17 |
|      2 |       5 |         18 |
+--------+---------+------------+

试试这个:

INSERT INTO junc_test_question (testFK, questionFK, ordinal)
VALUES (2, 17, (select * from (select ordinal+1 from junc_test_question order by ordinal desc limit 1) as p) );

对于下一个序号查询,相同的表的最大值并向其加 1。

INSERT INTO junc_test_question (testFK, questionFK, ordinal)
VALUES (?, ?, (
  select MAX(ordinal)+1 from  (select * from junc_test_question ) as rftable where testFK=?
) );

这是我的答案。