【问题标题】:How to make Oracle keep the case of identifiers as they appear in the query?如何让 Oracle 在查询中保留标识符的大小写?
【发布时间】:2021-01-24 13:07:58
【问题描述】:

我想使用一个使用 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 错误。

如何绕过这个?

UPD。我在创建数据库对象时尝试使用小写,例如:

CREATE TABLE "some_table"
(
    "some_column"       VARCHAR(10),
    "some_other_column" VARCHAR(10)
);

- 但是在这种情况下,Oracle 在执行上面的SELECT 语句时会引发错误,因为其中的标识符被转换为大写,而对象名称为小写。

UPD 2.

我不应该编辑第三方库的源代码 - 必须以某种方式配置我的环境和连接:Oracle、PHP、PDO。

【问题讨论】:

  • 我不懂 PHP,但是 - 就 Oracle 而言 - 如果您想保持字母大小写,请将这些 标识符 括在双引号中。看看有没有帮助。
  • @Littlefoot 如果我不是该库的开发人员,我该怎么做?您是否建议在他们使用 SQL 查询的每个地方覆盖他们的代码?
  • 呃,不。正如我所说,我不了解 PHP,我不知道它实际上是如何工作的。我希望其他人能够提供帮助。
  • @YourCommonSense, IMO, pdo 已经使用 case_natural - 这就是它以大写形式返回结果的原因。但是您给了我一个好主意-我会尝试强制它使用小写(因为库的作者使用小写)-也许会有所帮助

标签: php oracle pdo case-sensitive


【解决方案1】:

感谢Your Common Sense 的评论,我找到了解决方案。

初始化库时,我向它传递了一个 PDO 对象 - 我已通过以下代码将其配置为始终使用小写:

$options = [
    PDO::ATTR_CASE => PDO::CASE_LOWER,
];
$connection = new PDO($dsn, $username, $password, $options);
init3rdPartyLibrary($connection);

因此,$statement->fetch() 返回的 $result 变量的键现在是小写的,因此该库按其作者的预期工作。

【讨论】:

    【解决方案2】:

    如果您想使用小写标识符,那么正如您在问题中所写,您需要在 Oracle 中将它们双引号:

    CREATE TABLE "some_table"
    (
        "some_column"       VARCHAR(10),
        "some_other_column" VARCHAR(10)
    );
    

    如果您使用了区分大小写的标识符,那么您将总是在每次使用它们时都需要引用它们。所以你在 PHP 中的 SQL 语句应该是:

    $statement = $pdo->prepare('SELECT * from "some_table" where "some_column" = :some_column');
    

    一旦你在那里引用了它们,那么标识符将与数据库中的值匹配,返回的结果集也应该有小写的列标识符。

    如何绕过这个?

    来自 Oracle 的 Database Object Names and Qualifiers 文档:

    数据库对象命名规则

    每个数据库对象都有一个名称。在 SQL 语句中,您可以使用带引号的标识符或不带引号的标识符来表示对象的名称。

    • 带引号的标识符以双引号 (") 开头和结尾。如果使用带引号的标识符命名架构对象,则在引用该对象时必须使用双引号。
    • 未加引号的标识符不被任何标点符号包围。

    您可以使用带引号或不带引号的标识符来命名任何数据库对象。

    ...

    1. 不带引号的标识符不区分大小写。 Oracle 将它们解释为大写。带引号的标识符区分大小写。

    这意味着您不能在 Oracle 中绕过这一点,因为这是 Oracle 设计的行为方式。您可以引用标识符(在所有使用它们的地方)并且可以使用小写标识符,或者 Oracle 会将未引用的标识符隐式转换为大写。

    【讨论】:

      猜你喜欢
      • 2012-11-01
      • 1970-01-01
      • 2020-01-21
      • 1970-01-01
      • 1970-01-01
      • 2010-11-05
      • 1970-01-01
      • 2020-06-24
      • 2010-12-09
      相关资源
      最近更新 更多