【问题标题】:MySQL add values to SET elementMySQL将值添加到SET元素
【发布时间】:2016-01-20 22:45:19
【问题描述】:

我试图在 php 表单的帮助下向我的数据库中插入一个新行。

CREATE TABLE person (
first_name      VARCHAR(30) NOT NULL,
last_name       VARCHAR(30) NOT NULL,
languages       SET('english', 'greek', 'german', 'japanese', 'spanish', 'italian', 'french', 'wookie', 'klingon', 'other') NOT NULL,
pid             INT UNSIGNED NOT NULL AUTO_INCREMENT,
PRIMARY KEY(pid)
);

首先,我有上面的 MySQL 表。

然后,使用以下代码,我得到了所有内容的字段值

<form class="sform" method="post">
<input type="text" name="first_name" value="" placeholder="First name" maxlength="30">
<input type="text" name="last_name" value="" placeholder="Last name" maxlength="30">
<select multiple="multiple" id="languages" name="languages[]">
                <option value='english'>English</option>
                <option value='greek'>Greek</option>
                <option value='german'>German</option>
                <option value='japanese'>Japanese</option>
                <option value='spanish'>Spanish</option>
                <option value='italian'>Italian</option>
                <option value='french'>French</option>
                <option value='wookie'>Wookie</option>
                <option value='klingon'>Klingon</option>
                <option value='other'>Other</option>
            </select>
</form>

此时请注意这是一个多选表单。(一个人可能会说一种以上的语言)

然后,使用php 获取表中每个元素的值,但对于我最感兴趣的元素,我执行以下操作:

$qfirst_name     = $_POST['first_name'];
$qlast_name      = $_POST['last_name'];
$qlanguages      = "'" . implode("','", $_POST['languages']) . "'";

我在这里调用implode 方法的原因是,所以我得到了以下形式的字符串:ex.'english','greek' 但是,这不是 MySQL 接受初始化 SET 的方式,所以我替换了 single quotes 之类的所以:

$qlanguages = str_replace('\'', '', $qlanguages);

现在,$qlanguages 将是:ex.english,greek 但这还不够接近,所以最后一步是在变量的开头和结尾应用 quotes,如下所示:$qlanguages = '\''.$qlanguages.'\'';

最后,$qlanguages 以正确的形式'english,greek' 插入到数据库中,代码如下:

$sql1 = "INSERT INTO person (first_name, last_name, languages) 
         VALUES ('$qfirst_name', '$qlast_name', '$qlanguages')";

然后我连接到我的数据库以便将条目添加到数据库 注意这里还有另一个文件建立了连接,我刚刚包含它在我的 php 文件的顶部。

if ($dbconn->query($sql1)) {
    echo "SUCCESS";
}
else {
    echo "FAIL";
}

我已经尽我所能解释了我的步骤,我的问题是:为什么当我在查询中包含SET 字段时,我无法在数据库中插入新的person。我错过了什么?

抱歉,帖子太长了。

【问题讨论】:

  • 您没有解决数据的安全问题,更不用说将数据放入表中。您应该改用prepared statement
  • 此外,通过数据库查询来回答您的问题不是很好的方法$qlanguages 已经有' 围绕它。你应该这样做...VALUES ('$qfirst_name', '$qlast_name', $qlanguages)";

标签: php mysql


【解决方案1】:

你这样做了:

$qlanguages = "'english,greek'";
$sql1 = "INSERT INTO person (first_name, last_name, languages) 
     VALUES ('$qfirst_name', '$qlast_name', '$qlanguages')";

所以你得到了这个:

$sql1 = "INSERT INTO person (first_name, last_name, languages) 
     VALUES ('qfirst_name', 'qlast_name', ''english,greek'')";

您可以看到“双”“单”引号代替语​​言

【讨论】:

  • 您不知道,这困扰了我多长时间...非常感谢先生。这显然是一个新手错误,但我仍然是本科生:)
【解决方案2】:

SET 数据类型是 stored internally as a binary digit。 IIRC 您可以利用这一事实并省去所有这些字符串操作。另外,如果您将我放在该网页前 5 秒钟,我可以删除您的数据库。您应该使用准备好的语句来降低 SQL 注入攻击风险。

<form class="sform" method="post">
<input type="text" name="first_name" value="" placeholder="First name" maxlength="30">
<input type="text" name="last_name" value="" placeholder="Last name" maxlength="30">
<select multiple="multiple" id="languages" name="languages[]">
                <option value='1'>English</option>
                <option value='2'>Greek</option>
                <option value='4'>German</option>
                <option value='8'>Japanese</option>
                <option value='16'>Spanish</option>
                <option value='32'>Italian</option>
                <option value='64'>French</option>
                <option value='128'>Wookie</option>
                <option value='256'>Klingon</option>
                <option value='512'>Other</option>
            </select>
</form>


<?php
$qfirst_name     = $_POST['first_name'];
$qlast_name      = $_POST['last_name'];
$qlanguages      = array_sum($_POST['languages']);

$stmt = $dbconn->prepare("INSERT INTO person (first_name, last_name, languages) VALUES (?, ?, ?)");
$stmt->bind_param("ssd", $qfirst_name, $qlast_name, $qlanguages);
if ($stmt->execute($sql1)) {
    echo "SUCCESS";
}
else {
    echo "FAIL";
}
?>

未经测试,但几年前我做了类似的事情,当时我很愚蠢地使用了SET 列。现在我建议使用单独的语言表。

【讨论】:

  • 单独的语言表是 3NF(我认为),这就是为什么我认为它更好,我在几个小时前正在考虑这个问题,当时我无法弄清楚手头的 SET 问题。
猜你喜欢
  • 1970-01-01
  • 2016-08-02
  • 2021-12-10
  • 1970-01-01
  • 2011-03-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-23
相关资源
最近更新 更多