如何让 Oracle 保留标识符在查询中出现的大小写?
How to make Oracle keep the case of identifiers as they appear in the query?
我想使用一个使用 PDO 的 php 库。我想使用 Oracle 数据库。
问题是该库的作者在他们的查询中使用了不带引号的标识符,例如:
$statement = $pdo->prepare('SELECT * from some_table where some_column = :some_column');
$statement->execute(['some_column' => 'some value']);
$result = $statement->fetch(\PDO:FETCH_ASSOC);
return $result['some_other_column'];
在这种情况下,Oracle 将标识符的大小写转换为大写,但作者假设小写,因此出现 undefined index
php 错误。
我该如何绕过这个?
更新。我在创建数据库对象时尝试使用小写字母,例如:
CREATE TABLE "some_table"
(
"some_column" VARCHAR(10),
"some_other_column" VARCHAR(10)
);
- 但在这种情况下,Oracle 在执行上面的 SELECT
语句时会引发错误,因为其中的标识符被转换为大写,而对象名称为小写。
更新 2.
我不应该编辑第三方库的源代码 - 必须以某种方式配置我的环境和连接:Oracle、PHP、PDO。
如果你想使用小写标识符,那么,正如你在问题中所写的,你需要在 Oracle 中将它们用双引号引起来:
CREATE TABLE "some_table"
(
"some_column" VARCHAR(10),
"some_other_column" VARCHAR(10)
);
如果您使用了 case-sensitive 标识符,那么您将 总是 需要在每次使用它们时引用它们。所以你在 PHP 中的 SQL 语句应该是:
$statement = $pdo->prepare('SELECT * from "some_table" where "some_column" = :some_column');
一旦你在那里引用它们,标识符就会匹配数据库中的值,返回的结果集也应该有 lower-case 列标识符。
How do I bypass this?
来自 Oracle 的 Database Object Names and Qualifiers 文档:
Database Object Naming Rules
Every database object has a name. In a SQL statement, you represent the name of an object with a quoted identifier or a nonquoted identifier.
- A quoted identifier begins and ends with double quotation marks ("). If you name a schema object using a quoted identifier, then you must use the double quotation marks whenever you refer to that object.
- A nonquoted identifier is not surrounded by any punctuation.
You can use either quoted or nonquoted identifiers to name any database object.
...
- Nonquoted identifiers are not case sensitive. Oracle interprets them as uppercase. Quoted identifiers are case sensitive.
这意味着您无法在 Oracle 中绕过它,因为这是 Oracle 设计的行为方式。您要么引用标识符(在它们被使用的任何地方)并且可以有 lower-case 标识符,或者 Oracle 将隐式地将未引用的标识符转换为 upper-case.
感谢 Your Common Sense
的评论,我找到了解决方案。
初始化库时,我将一个 PDO 对象传递给它 - 我已通过以下代码将其配置为始终使用小写字母:
$options = [
PDO::ATTR_CASE => PDO::CASE_LOWER,
];
$connection = new PDO($dsn, $username, $password, $options);
init3rdPartyLibrary($connection);
因此,$statement->fetch()
返回的 $result
变量的键现在是小写字母,因此该库按其作者的预期工作。
我想使用一个使用 PDO 的 php 库。我想使用 Oracle 数据库。
问题是该库的作者在他们的查询中使用了不带引号的标识符,例如:
$statement = $pdo->prepare('SELECT * from some_table where some_column = :some_column');
$statement->execute(['some_column' => 'some value']);
$result = $statement->fetch(\PDO:FETCH_ASSOC);
return $result['some_other_column'];
在这种情况下,Oracle 将标识符的大小写转换为大写,但作者假设小写,因此出现 undefined index
php 错误。
我该如何绕过这个?
更新。我在创建数据库对象时尝试使用小写字母,例如:
CREATE TABLE "some_table"
(
"some_column" VARCHAR(10),
"some_other_column" VARCHAR(10)
);
- 但在这种情况下,Oracle 在执行上面的 SELECT
语句时会引发错误,因为其中的标识符被转换为大写,而对象名称为小写。
更新 2.
我不应该编辑第三方库的源代码 - 必须以某种方式配置我的环境和连接:Oracle、PHP、PDO。
如果你想使用小写标识符,那么,正如你在问题中所写的,你需要在 Oracle 中将它们用双引号引起来:
CREATE TABLE "some_table"
(
"some_column" VARCHAR(10),
"some_other_column" VARCHAR(10)
);
如果您使用了 case-sensitive 标识符,那么您将 总是 需要在每次使用它们时引用它们。所以你在 PHP 中的 SQL 语句应该是:
$statement = $pdo->prepare('SELECT * from "some_table" where "some_column" = :some_column');
一旦你在那里引用它们,标识符就会匹配数据库中的值,返回的结果集也应该有 lower-case 列标识符。
How do I bypass this?
来自 Oracle 的 Database Object Names and Qualifiers 文档:
Database Object Naming Rules
Every database object has a name. In a SQL statement, you represent the name of an object with a quoted identifier or a nonquoted identifier.
- A quoted identifier begins and ends with double quotation marks ("). If you name a schema object using a quoted identifier, then you must use the double quotation marks whenever you refer to that object.
- A nonquoted identifier is not surrounded by any punctuation.
You can use either quoted or nonquoted identifiers to name any database object.
...
- Nonquoted identifiers are not case sensitive. Oracle interprets them as uppercase. Quoted identifiers are case sensitive.
这意味着您无法在 Oracle 中绕过它,因为这是 Oracle 设计的行为方式。您要么引用标识符(在它们被使用的任何地方)并且可以有 lower-case 标识符,或者 Oracle 将隐式地将未引用的标识符转换为 upper-case.
感谢 Your Common Sense
的评论,我找到了解决方案。
初始化库时,我将一个 PDO 对象传递给它 - 我已通过以下代码将其配置为始终使用小写字母:
$options = [
PDO::ATTR_CASE => PDO::CASE_LOWER,
];
$connection = new PDO($dsn, $username, $password, $options);
init3rdPartyLibrary($connection);
因此,$statement->fetch()
返回的 $result
变量的键现在是小写字母,因此该库按其作者的预期工作。