父 - 事务下 PHP PDO SQLite 中的子表 - 没有错误,但它不起作用
Posted
技术标签:
【中文标题】父 - 事务下 PHP PDO SQLite 中的子表 - 没有错误,但它不起作用【英文标题】:Parent - child table in PHP PDO SQLite under transaction - No error but it doesn't work 【发布时间】:2022-01-22 03:30:48 【问题描述】:早上好, 我在下面编写了代码,它在事务下使用 PDO 和 SQLite 在 php 上运行。 莫名其妙地它没有出错,但它甚至没有写第二个表,结果记录的所有字段都为空。 你能告诉我我做错了什么,因为我在 Apache2 日志中找不到任何错误吗? 非常感谢。
我在 SQLite 中创建了两个表:
第一个包含问题数据; 第二个包含每个问题的详细信息创建数据库的我的 SQL 脚本:
CREATE TABLE "questionari" (
"pkid_questionario" INTEGER NOT NULL,
"dt_registrazione" TEXT NOT NULL,
"matricola" INTEGER NOT NULL,
"cognome" TEXT NOT NULL,
"nome" TEXT NOT NULL,
"email" TEXT NOT NULL,
"pk_localizzazione" INTEGER NOT NULL,
"desc_localizzazione" TEXT NOT NULL,
PRIMARY KEY("pkid_questionario" AUTOINCREMENT)
);
CREATE TABLE "t1" (
"idQuestionario" INTEGER,
"pkidBene" INTEGER,
"NumeroEtichetta" INTEGER,
"DescBene" TEXT,
"EsistenzaBene" TEXT,
"EsistenzaEtichetta" TEXT DEFAULT null,
"txtNote" TEXT DEFAULT null,
FOREIGN KEY("idQuestionario") REFERENCES "questionari"("pkid_questionario")
ON UPDATE CASCADE
ON DELETE CASCADE,
PRIMARY KEY("pkidBene","idQuestionario")
);
我的 PHP 代码是这样的:
define("T1_PkID","t1_PkID_r");
define("T1_Etichetta", "t1_Etichetta_r");
define("T1_Desc", "t1_Desc_r");
define("T1_Bene_YN", "t1_Bene_YN_r");
define("T1_Etichetta_YN", "t1_Etichetta_YN_r");
define("T1_Note", "t1_Note_r");
//[Omissis...]
try
$db = new SQLiteDB();
//$dbh = new PDO("sqlite:./DB/DB_Inventario.db");
$dbh = $db->connect();
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$dbh->beginTransaction();
$sql = "INSERT INTO questionari ";
$sql .= "(dt_registrazione, matricola, cognome, nome, email, pk_localizzazione, desc_localizzazione) VALUES ";
$sql .= "(:dt_registrazione, :matricola, :cognome, :nome, :email, :pk_localizzazione, :desc_localizzazione)";
$stmt = $dbh->prepare($sql);
$dt_registrazione = date('Y/m/d H:i:s');
$stmt->bindParam(":dt_registrazione", $dt_registrazione);
$stmt->bindParam(":matricola", $matricola);
$stmt->bindParam(":cognome", $cognome);
$stmt->bindParam(":nome", $nome);
$stmt->bindParam(":email", $email);
$stmt->bindParam(":pk_localizzazione", $pkLocalizzazione);
$stmt->bindParam(":desc_localizzazione", $DescLocalizzazione);
$stmt->execute();
$lastID = $dbh->lastInsertId();
// t1_NumRows is the rows number to write for t1
for($i=0;$i<$t1_NumRows;$i++)
$sql = "INSERT INTO t1 ";
$sql .= "(idQuestionario, pkidBene, NumeroEtichetta, DescBene, EsistenzaBene, EsistenzaEtichetta, txtNote) VALUES ";
$sql .= "(:p_idQuestionario, :p_pkidBene, :p_NumeroEtichetta, :p_DescBene, :p_EsistenzaBene, :p_EsistenzaEtichetta, :p_txtNote)";
$stmt->bindParam(":p_idQuestionario", $lastID, PDO::PARAM_INT);
$stmt->bindParam(":p_pkidBene", $_POST[T1_PkID.$i], PDO::PARAM_INT);
$stmt->bindParam(":p_NumeroEtichetta", $_POST[T1_Etichetta.$i], PDO::PARAM_INT);
$stmt->bindParam(":p_DescBene", $_POST[T1_Desc.$i], PDO::PARAM_STR, 500);
$stmt->bindParam(":p_EsistenzaBene", $_POST[T1_Bene_YN.$i], PDO::PARAM_STR, 2);
if($_POST[T1_Bene_YN . $i]=="NO")
$stmt->bindParam(":p_EsistenzaEtichetta", null, PDO::PARAM_STR, 2);
else
$stmt->bindParam(":p_EsistenzaEtichetta", $_POST[T1_Etichetta_YN.$i], PDO::PARAM_STR, 2);
if(strlen(trim($_POST[T1_Note.$i]))==0)
$stmt->bindParam(":p_txtNote", null, PDO::PARAM_STR, 500);
else
$stmt->bindParam(":p_txtNote", $_POST[T1_Note.$i], PDO::PARAM_STR, 500);
$stmt = $dbh->prepare($sql);
$stmt->execute();
//[Omissis...]
$dbh->commit();
// In case of exception make rollback!
这是记录第一个问题后“t1”上的结果,有两个细节:
【问题讨论】:
我没有看到$t1_NumRows
定义,所以它永远不会进入循环
$ t1_NumRows 是一个由加载的表单设置的值 $ _POST [] 表示要发布的行数。在我的测试用例中是 2。
尝试一些故障排除。在此过程中添加一些回显或记录行,例如在 for 循环内部。检查循环内的PDO errors 以确保查询没有失败。
【参考方案1】:
好的,我在代码中进行了一些调试,发现必须在参数查询的定义之后立即插入准备语句。 此时我的代码有效:D:D
for($i=0;$i<$t1_NumRows;$i++)
$sql = "INSERT INTO t1 ";
$sql .= "(idQuestionario, pkidBene, NumeroEtichetta, DescBene, EsistenzaBene, EsistenzaEtichetta, txtNote) VALUES ";
$sql .= "(:p_idQuestionario, :p_pkidBene, :p_NumeroEtichetta, :p_DescBene, :p_EsistenzaBene, :p_EsistenzaEtichetta, :p_txtNote)";
$stmt = $dbh->prepare($sql);
$stmt->bindParam(":p_idQuestionario", $lastID, PDO::PARAM_INT);
$stmt->bindParam(":p_pkidBene", $_POST[T1_PkID.$i], PDO::PARAM_INT);
$stmt->bindParam(":p_NumeroEtichetta", $_POST[T1_Etichetta.$i], PDO::PARAM_INT);
$stmt->bindParam(":p_DescBene", $_POST[T1_Desc.$i], PDO::PARAM_STR, 500);
$stmt->bindParam(":p_EsistenzaBene", $_POST[T1_Bene_YN.$i], PDO::PARAM_STR, 2);
if($_POST[T1_Bene_YN . $i]=="NO")
$stmt->bindValue(":p_EsistenzaEtichetta", null, PDO::PARAM_STR, 2);
else
$stmt->bindParam(":p_EsistenzaEtichetta", $_POST[T1_Etichetta_YN.$i], PDO::PARAM_STR, 2);
if(strlen(trim($_POST[T1_Note.$i]))==0)
$stmt->bindValue(":p_txtNote", null, PDO::PARAM_STR, 500);
else
$stmt->bindParam(":p_txtNote", $_POST[T1_Note.$i], PDO::PARAM_STR, 500);
$stmt->execute();
【讨论】:
以上是关于父 - 事务下 PHP PDO SQLite 中的子表 - 没有错误,但它不起作用的主要内容,如果未能解决你的问题,请参考以下文章