当我运行以下命令时:
SELECT p.*,
(SELECT i.image
FROM pimage i
WHERE p.id = i.pid
ORDER BY i.id ASC
LIMIT 1
) as image
FROM products p
WHERE p.categories LIKE '%$subCatId%'
ORDER BY p.id ASC
在包含以下表格的数据库中:
pImage
products
sidebar
specs
我收到错误:
不幸的是,我今天下午在我的制作网站上以纯文本打印了十几次。#1142 - 对表'pimage'的用户'database_user'@'localhost'拒绝SELECT命令
我在网站的本地版本发布之前测试了它,它运行得很好。我很快恢复了变更,并在开发网站上进行了测试。当存储在PHP代码中时,它在开发服务器上运行得很好。我还在开发服务器的phpMyAdmin界面上测试了它,它运行正常。我登录到生产网站的phpMyAdmin界面,然后在那里运行查询,但失败了同样的错误。我单独在每个表上运行查询,并且它们没有错误地运行。
是什么给了什么?!?
制作网站已经过时了。它正在运行FreeBSD 6.4(是的,EOL是2010年11月30日......)和MySQL 5.1(是的,EOL是2013年12月31日......)。我正在努力从共享主机移动它,所以我可以更新它。开发服务器是当前的Bitnami LAMP堆栈虚拟机,运行Ubuntu 14.04和MySQL 5.5。到目前为止,我没有兼容性问题。据我所知,查询不使用两个版本之间不同的任何语法或特殊功能。
答案 0 :(得分:0)
我以管理用户身份登录数据库,并返回错误:
#1146 - 表'company.pimage'不存在
可以快速解决原始问题:pimage
和pImage
之间的愚蠢案例错误。
之前未检测到此错误,因为Bitnami设备更改了默认值以使其表名不区分大小写,并且因为MySQL中非管理员用户的错误消息不会泄漏信息。
MySQL文档,section 9.2.2 "Identifier Case Sensitivity"读取:
默认情况下,表别名在Unix上区分大小写
但这可以通过lower_case_table_names
系统变量进行更改。
如果设置为0,表名将按指定的方式存储,并且比较区分大小写。如果设置为1,则表名称以小写形式存储在磁盘上,并且比较不区分大小写。如果设置为2,则表名存储为给定但以小写字母比较...
在Unix上,lower_case_table_names的默认值为0.在Windows上,默认值为1.在OS X上,默认值为2.
在我的开发服务器上,SHOW VARIABLES
演示了Bitnami设备将此值设置为1. mysqld --verbose --help
表示已编译的默认值将此值设置为零,但是as described on the bitnami forums, /opt/bitnami/mysql/scripts/ctl.sh
设置--lower-case-table-names=1
。
非管理员用户的错误消息很神秘:
#1142 - 对表'mispelled_table'的用户'user @ localhost'拒绝SELECT命令
但管理员用户的错误消息:
#1146 - 表'company.mispelled_table'不存在
很容易理解。管理员用户具有SHOW GRANTS FOR CURRENT_USER
权限:
GRANT USAGE ON *.* TO 'admin_user'@'%' IDENTIFIED BY PASSWORD [redacted]
GRANT ALL PRIVILEGES ON `company`.* TO 'admin_user'@'%' WITH GRANT OPTION
但普通用户具有以下权限:
GRANT USAGE ON *.* TO 'user'@'localhost' IDENTIFIED BY PASSWORD [redacted]
GRANT SELECT ON `schap`.`pImage` TO 'user'@'localhost'
GRANT SELECT, SELECT (view_count), UPDATE (view_count) ON `company`.`products` TO 'user'@'localhost'
...etc.
最后一点只是猜想,因为我没有必要的权限来更改和测试它,但我认为SHOW_DATABASES
privilege会给用户提供良好的错误消息。避免列出所有数据库名称可能是一个很好的策略,因为它可以防止黑客很容易地确定哪些表存在,但肯定会造成很多混乱!