不确定sql查询有什么问题

时间:2017-11-11 05:46:26

标签: php sql

把头发拉到这里试图弄清楚什么是错的,下面的代码用于过滤搜索。除非指定了位置 AND 类别,否则它都有效。除了通过类别,文本和作者搜索之外,指定位置,文本和作者也是如此。 非常感谢帮助,欢呼。

来自catch的错误消息是:exception' PDOException'消息' SQLSTATE [23000]:完整性约束违规:1052列' locationid'在where where子句中含糊不清'在D:\ xampp \ htdocs \ eden \ PET \ admin \ content \ index.php:344堆栈跟踪:#0 D:\ xampp \ htdocs \ eden \ PET \ admin \ content \ index.php(344):PDOStatement- >执行(数组)#1 {main}

第344行是:$ s-> execute($ placeholders);

我的代码:

if (isset($_GET['action']) and $_GET['action'] == 'search')
{
include $_SERVER['DOCUMENT_ROOT'] . '/eden/PET/includes/db.inc.php';

$select = 'SELECT *';
$from   = ' FROM content';
$where  = ' WHERE TRUE';
$placeholders = array();

if ($_GET['author'] != '') // An author is selected
{
  $where .= " AND authorid = :authorid";
  $placeholders[':authorid'] = $_GET['author'];
}

if ($_GET['category'] != '') // A category is selected
{
  $from  .= ' INNER JOIN contentcategory ON id = contentid';
  $where .= " AND categoryid = :categoryid";
  $placeholders[':categoryid'] = $_GET['category'];
}

if ($_GET['locationid'] != '') // A location was selected
{
  $where .= " AND locationid = :locationid";
  $placeholders[':locationid'] = $_GET['locationid'];
}

if ($_GET['text'] != '') // Some search text was specified
{
  $where .= " AND contenttext LIKE :contenttext";
  $placeholders[':contenttext'] = '%' . $_GET['text'] . '%';
}

try
{
  $sql = $select . $from . $where;
  $s = $pdo->prepare($sql);
  $s->execute($placeholders);
}
catch (PDOException $e)
{
  $error = 'Error fetching contents!';
  include 'error.html.php';
  exit();
}

foreach ($s as $row)
{
  $contents[] = array('id' => $row['id'], 'text' => $row['contenttext'], 
  'locationid' => $row['locationid']);
}

include 'contents.html.php';
exit();
}

1 个答案:

答案 0 :(得分:1)

  

where子句中的列'locationid'是不明确的'

这是一种相当正式的语言,“有超过1列名为locationid

第二个locationid列来自contentcategory表,如果有类别,则只有JOIN。这就是为什么只有这种精确的过滤器组合才能解决问题。

由于数据库无法确定您的意思locationid,因此您需要通过将AND locationid =更改为AND content.locationid =来明确告知它。

正如@Wodin在评论中所说,如果你习惯于总是指定你所指的那个确切的列,你将永远不会再遇到这个错误。特别是如果你需要在表中添加一个列,然后不知道为什么一些看似无关的查询会突然失败。 如果您想在每个字段之前添加contentcontentcategory,则可以使用表别名:

SELECT c.*
FROM content AS c
INNER JOIN contentcategory AS cc ON c.id = cc.contentid
WHERE cc.categoryid = :categoryid AND c.locationid = :locationid