我收到以下错误:
2016-04-26 15:11:56 --- DEBUG:将用户数据插入遗留数据库时发生错误:Database_Exception [0]:[1064]您的SQL语法中有错误;查看与您的MySQL服务器版本对应的手册,以获得正确的语法,以便在附近使用')'在第1行~APPATH / classes / database / mysqli.php [179]
对于php查询:
$result = $usdb->query(Database::INSERT, "INSERT INTO users (id, `password`, group_id , active, created, updated) VALUES ({$user['id']}, {$user['password']}, {$user['group_id']}, {$user['active']}, {$user['created']}, {$user['updated']})");
以下是列类型:
id : int AI PK
password : varchar
group_id : int
active : tinyint
created : int
updated : int
答案 0 :(得分:1)
您需要在SQL查询的值周围使用单引号'
,假设它们是数据库中的字符串(而不是整数)。
列和表引用可以使用反引号进行封装,尽管它们不必使用,假设它们没有使用保留关键字。另一方面,值通常需要单引号(当然,除非您通过预准备语句准备值;或者如果您确定数据库模式使用整数类型)
在整数周围使用单引号也可以,所以用单引号括起任何值可能是安全的,如下所示:
$result = $usdb->query(
Database::INSERT,
"INSERT INTO users (id, `password`, group_id , active, created, updated)
VALUES (
'{$user['id']}',
'{$user['password']}',
'{$user['group_id']}',
'{$user['active']}',
'{$user['created']}',
'{$user['updated']}'
)
"
);
您应该始终使用参数化查询(预准备语句)。将原始PHP变量注入SQL查询是非常不安全的。如果你有一个带有单引号的变量,它将破坏你的SQL语句的逻辑。
您可以在the PHP manual中阅读有关预准备陈述的更多信息。
那么你的SQL应该真正的样子是这样的:
$sql = "
INSERT INTO users (id, `password`, group_id , active, created, updated)
VALUES (
:id,
:password,
:group_id,
:active,
:created,
:updated
)
";
然后将您的实际值绑定到准备好的语句中。
答案 1 :(得分:0)
由于password
列的类型为VARCHAR
,因此值$user['password']
应封装在单引号中。由于其余列的类型为INT
或TINYINT
,因此不需要单引号。
所以你的查询应该是这样的:
$result = $usdb->query(Database::INSERT, "INSERT INTO users (`id`, `password`, `group_id` , `active`, `created`, `updated`)
VALUES (" . $user['id'] . ", '"
. $user['password'] . "', "
. $user['group_id'] . ", "
. $user['active'] . ", "
. $user['created'] . ", "
. $user['updated']
. ")");
您应该对表名和列名使用反引号(`),对字符串使用单引号(')。只有在您的表名或列名为MySQL reserved word时才需要反引号,但这是避免使用保留字的最佳做法。
旁注:使用PDO prepare阻止您的数据库进行任何类型的SQL注入。
来自 PDO :: prepare
为将使用不同参数值多次发出的语句调用PDO :: prepare()和PDOStatement :: execute()通过允许驱动程序协商客户端和/或服务器端缓存来优化应用程序的性能查询计划和元信息,通过消除手动引用参数的需要,有助于防止SQL注入攻击。