如何让 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.

...

  1. 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 变量的键现在是小写字母,因此该库按其作者的预期工作。