【问题标题】:Foreign Key contraints MySQL外键约束 MySQL
【发布时间】:2015-05-18 20:47:47
【问题描述】:

我试图在这里插入两个表,一个是创建一个文档,该文档进入我的 doc_list 表,另一个从复选框中获取 ID 并将它们发布到连接表中。

问题是连接表需要一个我正在创建的帖子的 id,但我根本无法提供它,所以我收到了错误。

问题出在这里:$docId = $dbh->lastInsertId();

SQLSTATE[23000]:完整性约束违规:1452 无法添加或更新子行:外键约束失败(dashboardr.cat_doc_link_table,CONSTRAINT cat_doc_link_table_ibfk_2 FOREIGN KEY (link_doc_id) REFERENCES doc_list (doc_id) 在更新级联时删除级联)

如果我将其更改为:$docId = $_POST["doc_id"];

SQLSTATE[23000]:违反完整性约束:1048 列 'link_doc_id' 不能为空

这是我发布的表格:

<?php include 'header.php'; ?>
<?php 

require_once '../../db_con.php'; 

try{
    // Selecting entire row from cat_list table
    $results = $dbh->query("SELECT * FROM cat_list");

}catch(Exception $e) {
    echo $e->getMessage();
    die();
}

$category = $results->fetchAll(PDO::FETCH_ASSOC);

?>


<h3 class="subTitle">
    <i class="fa fa-pencil"></i></span> Create New Document
</h3>

<form action="actions/newDocAdd.php" method="post" id="rtf" name="">

    <input type="text" name="doc_title" id="doc_title" required="required" placeholder="Document Title"/><br />

    <input type="hidden" name="action" value="doc_id"/>

<label><input type="checkbox" name="" class="selectall"/> Select all</label>

<div id="checkboxlist">
    <?php
        foreach($category as $cat){ 
    ?>

    <input type="checkbox" value="<?php echo $cat["cat_id"]; ?>" name="cat_no[]"><?php echo $cat["cat_title"]; ?></a>
    <br>

    <?php
    }
    ?>
</div> 

    <textarea name="doc_content" id="doc_content" placeholder="Document Content" style="display: none;"></textarea>
    <iframe name="editor" id="editor" style="width:100%; height: 600px;"></iframe>

    <br><br> 
    <input onclick="formsubmit()" type="submit" value="Create Document" name="submit"/>


</form>

这是执行表单的脚本:

    /*******************************************************************
    **  ACTION SCRIPT TO POST A NEW CATEGORY INTO THE DOC_LIST TABLE  **
    *******************************************************************/


    if(isset($_POST["action"])){
    if(isset($_POST["submit"])){
    include_once'../../config.php';

    try {

    $dbh = new PDO("mysql:host=$hostname;dbname=dashboardr",$username,$password);
    $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $sql = "INSERT INTO doc_list (doc_title, doc_content, doc_created, user_id) 
            VALUES ('".$_POST["doc_title"]."','".$_POST["doc_content"]."',NOW(), '".$_SESSION['user']."')";

    $SQL = "INSERT INTO `cat_doc_link_table`(`link_cat_id`, `link_doc_id`) VALUES";
    $values = "";
    $params = [];
    $docId = $dbh->lastInsertId();

    foreach($_POST["cat_no"] as $cat)
    {
        $values.= "(?, ?), ";
        $params[] = $cat["cat_id"];
        $params[] = $docId;
    }
    $values = substr($values, 0, -2);
    $SQL.= $values;
    $query = $dbh->prepare($SQL);
    $query->execute($params);       

    if ($dbh->query($sql)) {

        header ('Location: ../docList.php?success=1');
    }else{
    }

    $dbh = null;
        }catch(PDOException $e)
    {
        echo $e->getMessage();
    }

    }

    }


    ?>

我对关系表相当陌生,所以请保持温和,因为我真的很想了解错误以及如何纠正这个问题,因为我非常接近解决问题。

【问题讨论】:

  • 请发布变量$SQL 的内容,以便我们可以看到最终的字符串是什么,以及print_r($params)。您还拥有$sql,这是不同的,并且容易受到没有占位符的 SQL 注入的影响。该语句很容易失败,但看起来您在调用 $dbh-&gt;query($sql) 之前调用了 lastInsertId() - 这是执行第一个插入并因此生成插入 ID 的原因。
  • 我对混淆的代码表示歉意 - 如果你不介意的话,你能否发布一个关于我应该在哪里打电话给 lastInsertId() 的消息?
  • 我看看能不能拼凑起来。不过我想看看print_r($_POST['cat_no'])
  • @MichaelBerkowski 她是我打印$sql = INSERT INTO doc_list (doc_title, doc_content, doc_created, user_id) VALUES ('dsfdg','dfgfd',NOW(), '10')的结果
  • $sql 很容易理解,但请发布另一个 $SQL。那是一个多插入并且有更复杂的字符串操作。

标签: php mysql pdo


【解决方案1】:

试试这个:

$dbh = new PDO("mysql:host=$hostname;dbname=dashboardr",$username,$password);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$insertDocList = $dbh->prepare("INSERT INTO doc_list (doc_title, doc_content, doc_created, user_id) 
    VALUES (:docTitle, :docContent, NOW(), :user)");

if( $insertDocList === false ) {
    die("statement couldn't be prepared");
}

$insertResult = $insertDocList->execute(array( 
    'docTitle'      => $_POST['doc_title'],
    'docContent'    => $_POST['doc_content'],
    'user'          => $_SESSION['user']
));

if( $insertResult === false ) {
    die("Insert Failed");
}

$docId  = $dbh->lastInsertId();

$SQL = "INSERT INTO `cat_doc_link_table`(`link_cat_id`, `link_doc_id`) VALUES";
$values = "";
$params = [];
//...

【讨论】:

  • SQLSTATE[42000]:语法错误或访问冲突:1065 查询为空
  • @phpcoder,理想情况下,你会使用调试器......但如果没有调试器,你可以使用die()。试试上面的方法,让我知道执行了什么语句。
  • 好的,所以得到这个 SQLSTATE[42000]:语法错误或访问冲突:1065 查询为空
  • @phpcoder,注释掉你的 setAttribute 以抛出异常,让 die() 语句在适用时执行。
  • 如果你没有得到任何一个 die() 语句,那么你的问题将与底部查询...
【解决方案2】:

您需要先执行第一个INSERT,然后再尝试使用$dbh-&gt;lastInsertId

$sql = "INSERT INTO doc_list (doc_title, doc_content, doc_created, user_id)
                VALUES (:doc_title, :doc_content, NOW(), :user_id)";
$stmt = $dbh->prepare($sql);
$stmt->execute(array(':doc_title' => $_POST["doc_title"],
                     ':doc_content' => $_POST["doc_content"],
                     ':user_id' => $_SESSION["user"]));
$docId = $dbh->lastInsertId;

此代码应位于代码中的 foreach 循环之前。你应该摆脱对$dbh-&gt;query($sql)的调用。

【讨论】:

  • 您好像更改了我的变量?你能用我的代码举个例子吗?
  • 我收到此错误 SQLSTATE[42000]: 语法错误或访问冲突:1064 您的 SQL 语法有错误;检查与您的 MySQL 服务器版本相对应的手册,以在第 1 行的 ''6', NULL)' 附近使用正确的语法
  • 我看不出这是从哪里来的,我的查询中没有 NULL
  • 我怎样才能知道?
  • 你摆脱了$dbh-&gt;query($sql),对吧?此代码执行该查询,您不应再执行此操作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-01-01
  • 2014-06-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多