我正在寻找一种方法来使用通配符和以下mysql查询。
public function getSetsOnMonth($setsId, $setsDate, $offset, $count)
{
$sql = sprintf("SELECT * FROM " . $this->_prefix . "media_set AS f
INNER JOIN " . $this->_prefix . "media_set_sets_assoc AS fs
ON fs.set_id = f.set_id AND fs.sets_id = '%s'
WHERE f.posted LIKE '%s'
AND f.is_active = 1
ORDER BY f.set_id DESC
LIMIT %s, %s",
mysql_real_escape_string($setsId),
mysql_real_escape_string($setsDate),
mysql_real_escape_string($offset),
mysql_real_escape_string($count));
echo $sql; exit;
$rs = mysql_query($sql);
$rows = array();
while ($row = mysql_fetch_object($rs)) {
$rows[] = $row;
}
mysql_free_result($rs);
return new XXX_Model_RecordSet($rows, $this);
}
我要做的是按月进行,以便(如果找到'LI''%s') 我已尝试以各种方式使用%,它总是出错。 例如(其中f.posted LIKE'%s%')返回此错误(警告:sprintf():..中的参数太少。)。
我也试过使用(其中f.posted LIKE'$ setsDate%')这不会返回sql错误,但它会使我的查询限制与日期相同,并且在%符号后删除单引号在sql打印输出中。
奇怪的是,如果我反转并将百分号放在$ setsDate(%setsDate)前面,则取消%后面的所有内容并显示所有内容。任何帮助将不胜感激。
更新时间:美国东部时间下午9点35分
这是sql输出('%s %%'): SELECT * FROM media_set AS f INNER JOIN media_set_sets_assoc AS fs ON fs.set_id = f.set_id AND fs.sets_id ='1'WERE f.posted LIKE'201312%'和f.is_active = 1 ORDER BY f.set_id DESC LIMIT 0 ,18
这是SQL输出('%s %%'): 点击'201312%'
注意之间没有空格。
答案 0 :(得分:1)
我相信你应该逃避在LIKE声明中使用的百分号,如下:
WHERE f.posted LIKE '%s %%'
答案 1 :(得分:0)
您的问题是sprintf
将%
视为特殊字符,因此当您需要实际的%
字符时会感到困惑。解决方法是在需要实际的%%
字符时使用%
。
但是,请不要使用sprintf 在SQL中插入值。这是一种非常糟糕的做法,它负责PHP代码中的大多数安全漏洞。逃避你的字符串是不够的。改为使用参数化查询。
您应该使用支持参数化查询的PDO或mysqli扩展。
有很多文章解释了为什么不应将值拼接到SQL中。这是一个:http://blog.codinghorror.com/give-me-parameterized-sql-or-give-me-death/
应该这样做的方式在此处讨论:https://stackoverflow.com/a/60496/219155