我正在开发一个PHP项目。我使用的是MySQL数据库,但我决定迁移到Postgres,因为使用Openlayers和Geoserver可以更好地优化(简单工作)。 我正在使用PDO,因为他们承诺可以轻松迁移到不同的数据库。
我遇到了WHERE子句的基本问题。我的代码是:
$query = Database::$DB->prepare('SELECT * FROM users WHERE ID=?;');
但是,我收到一个错误:
致命错误:未捕获的异常' PDOException'与消息 ' SQLSTATE [42703]:未定义列:7错误:列" id"才不是 存在LINE 1:SELECT * FROM users WHERE ID = $ 1;
我将代码更改为:
$query = Database::$DB->prepare('SELECT * FROM users WHERE "ID"=?;');
它有效。
当我学习PDO时,我没有经历过引用标识符的问题。我的项目很大,在WHERE子句中引用所有标识符会有很多工作,但如果需要这样做就没问题。
在我这样做之前,我想问一个人,对这件事情有所了解。
答案 0 :(得分:3)
这与PDO无关,而与底层数据库无关。 PDO是一个非常轻量级的包装器,并且不会对查询进行复杂的重新映射,以处理不同风格的DBMS接受的SQL差异。
在Postgres中,所有标识符(如表名和列名)都区分大小写,如果未引用则折叠为小写输入。因此,ID
与id
的列名不同,但WHERE ID=5
会自动翻译为WHERE id=5
。
"封装"在双引号中是Postgres如何引用标识符,相当于MySQL中的反引号或MS SQL Server中的方括号。他们保留案例以及允许像空格这样的东西,所以WHERE "ID"=5
告诉Postgres你真的意味着大写。
引用示例:
-- MySQL
SELECT * FROM `table with a space`;
-- PostgreSQL
SELECT * FROM "table with a space";
-- MS SQL Server
SELECT * FROM [table with a space]
最简单的解决方案是以小写命名所有Postgres表和列。缺点是来自SELECT ID FROM users WHERE ...
之类的查询的结果将返回结果中的小写键,这可能会破坏PHP代码的进一步假设。作为妥协,您可以修复SELECT
子句,将大写形式用作别名,如SELECT id as "ID" FROM users WHERE ...