【问题标题】:Escaping reserved SQL Server keywords through PHP通过 PHP 转义保留的 SQL Server 关键字
【发布时间】:2012-06-18 20:59:09
【问题描述】:

我用 PHP 为 SQL Server 数据库编写的查询遇到了一个问题,即单词未被识别为表名。我将 SQL Server 用于 PHP 2.0 (VC6)。当在 SQL Server Management Studio 中执行时,以下查询有效并返回表 Order 中的所有订单。

SELECT * FROM "db_name"."dbo"."Order" (also tried using brakets [] around table name)

在 PHP 中,我收到以下错误:

[0] => Array
    (
        [0] => IMSSP
        [SQLSTATE] => IMSSP
        [1] => -35
        [code] => -35
        [2] => Invalid type
        [message] => Invalid type
    )

此查询在 PHP 代码中适用于数据库中所有其他表 db_name.. 它只是不适用于表 Order,这是正确的表名。我尝试了双引号、方括号、无引号/括号等,但均无济于事。有谁知道如何解决这个问题?

** 更新:

我找到了解决方案。请查看修复或解决方法的答案之一。

【问题讨论】:

  • PHP 代码中使用的确切 SQL 查询是什么,正在使用什么驱动程序/适配器?
  • 您是否研究过实际收到的 PHP 错误代码?
  • 正在使用的确切查询在帖子中(数据库名称替换为dB_name)。我正在使用 MS SQL for PHP 2.0 作为驱动程序。

标签: php sql sql-server


【解决方案1】:

PHP 或您的驱动程序中一定发生了某些事情。您应该能够使用 SQL Server Profiler 查看正在提交的实际查询。

无论如何,如果你不知道它在做什么。您可以将此视为一种解决方法:

CREATE VIEW dbo.MyOrder
AS
SELECT * FROM [Order]

继续前进 - 生命太短暂了。

【讨论】:

  • 那么,我通过 PHP 创建的视图没有出现在 MSSQL Mgnt Studio 上是否有原因,反之亦然。我正在使用Select VIEW_DEFINITION From INFORMATION_SCHEMA.VIEWS; 来查看视图。无论如何,我尝试为表 OrderItem 创建一个视图,并使用此视图通过 PHP 检索行。这行得通。但是,对于表Order,它仍然不起作用。我做了
  • 我创建的视图(全部在 PHP 代码中完成):CREATE VIEW myOrderItems AS SELECT * FROM [db_name].[dbo].[OrderItem];CREATE VIEW myOrders AS SELECT * FROM [db_name].[dbo].[Order];SELECT FROM myOrderItems WHERE OrderID='1234'; 有效。 SELECT FROM myOrders WHERE OrderID='1234'; 不起作用。
  • 还有一件事:sqlsrv_error() 不会产生错误。它是 NULL。
  • @user796837 从 PHP 创建视图可能仍然会遇到与最初在 PHP 中转义相同的问题。为什么不在 SSMS 中创建视图?它们将是模式对象并永久存在于数据库中。
  • @user796837 您是否通过分析器查看实际提交给 SQL Server 的 wuery 是什么,查询是否被 PHP 或驱动程序以某种方式破坏?
【解决方案2】:

好吧,我找到了解决问题的方法。这是我的规格:

  • Windows 7 64 位
  • PHP 5.3 VC9 编译(在尝试解决此问题时从 VC^ 版本更新)
  • 驱动程序:SQL for PHP 2.0 (VC9)
  • 我试图从中提取数据的表名:[Order]
  • 我使用的查询:SELECT * FROM [db_name].[dbo].[Order] WHERE ...

上面的查询根本不适用于 PHP 中的 Order 表,而它在 SSMS 中运行良好。 db_name 中的所有其他表也查询得很好。我尝试创建视图或使用别名,但它们都不适用于Order

我应该从一开始就想到这一点,但我最终尝试只查询一列,例如[OrderID],你知道什么?只要您一一列出查询中的列名,它就可以工作。我相信 MySQL 不支持 MSSQL 中的列之一。所以,

SELECT [OrderID],[OrderNumber],... FROM [db_name].[dbo].[Order] WHERE ...

工作得很好!我希望这会在将来为某人省去一些痛苦。

【讨论】:

    【解决方案3】:

    当查询返回 PDO 无法处理的列类型时会发生此错误。例如,当您尝试时会得到这个

    SELECT default_value FROM sys.parameters
    

    因为该列是 sql_variant 类型。如果有意义,不如将该列转换为 varchar 或其他内容,或者将其从查询中删除。

    在您的情况下发生的可能是该表上有一个奇怪类型的列,当您明确命名所需的列时,该列被消除了。

    【讨论】:

      【解决方案4】:

      不能将表命名为“订单”:这是reserved word in SQL

      在很多情况下,您可以在引号(或反引号)之间使用此名称,但您总是会遇到无法处理的情况。重命名此表。

      如果你不能尝试别名:

      SELECT * FROM "db_name"."dbo"."Order" as ord
      

      【讨论】:

      • 什么时候不能使用带引号的标识符? (也就是说,在什么语法构造?我不反对应该选择一个更好的名字......)
      • 但是在我连接的第三方程序中它被命名为Order。如果我更改此表名,它将破坏程序。有没有办法对Order这个词进行转义或使用别名,这样它就不会与保留字冲突?我认为 [] 或 "" 转义了任何字符串?
      • 在大多数数据库(包括 SQL Server)中,保留字可以用作表名,只要它们用双引号(或 SQL Server 的括号)括起来。
      • 但不是每个司机都有。问题似乎来自映射。这就是为什么我也建议使用别名。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-02-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多