【问题标题】:Simple SELECT statement fails with "syntax to use near", "ORA-00906", "syntax error at or near" or "syntax near the keyword"简单的 SELECT 语句失败,出现“要使用的语法”、“ORA-00906”、“在或附近出现语法错误”或“在关键字附近的语法”
【发布时间】:2014-05-23 15:47:36
【问题描述】:

我有一个非常简单的 SQL 语句

SELECT * FROM Table;

但是,我的查询引擎返回了一个语法错误。为什么?

错误详情:

“System.Data.SqlClient.SqlException”类型的未处理异常发生在 >System.Data.dll

附加信息:关键字“Table”附近的语法不正确。

这怎么可能?我检查了连接字符串,它是正确的。 我检查了我的表名,它也是正确的。

我做错了什么?

【问题讨论】:

  • 你的桌子叫什么名字? table 本身就是一个保留字。
  • "Table" 是保留关键字,请将您的表称为其他关键字
  • 如果它被称为Table,在它周围加上方括号 - [Table] (但是,不要叫它table。改变那个名字!)
  • @MichaelB:不!如果它被称为table,那么重命名它是正确的做法。 table 没有透露任何内容。
  • @JoJo,一般来说,我会考虑让表名更能说明它们所代表的内容。 “Table1”中包含什么? (除非您正在为物理表建模,但这是一个不常见的用例:))

标签: sql select


【解决方案1】:

好的,Table 是所有 SQL 变体中的保留关键字。

如果你想调用一个表Table,并在语句中使用它,你必须告诉你的sql引擎它是一个标识符。为此,您需要使用 Identifier Qualifiers

对于(MS SQL Server)TSQL使用方括号

SELECT * FROM [Table];

对于 MySQL 使用 `

SELECT * FROM `Table`;

对于 Oracle 和 PostgreSQL 使用引号, 这些都是符合标准的。

SELECT * FROM "Table";

对于 SQLite,您可以使用上述任何一种,但首选引号。

标识符限定符告诉引擎这是一个标识符(对象的名称)。不是关键字的名称,即使它们恰好相同。如果没有您的指导,查询引擎可能会感到困惑并报告错误,或者更糟糕的是,会出现意外情况。

使用标识符限定符是一种很好的做法,即使标识符不是关键字。 他们更好地为所有解析器定义语句,包括肉体类型。

在关键字之后命名对象通常被认为是不好的做法。因此,您应该尽量避免使标识符与关键字相同。保留关键字描述表格内容的情况很少见,请参见脚注。

例如您的表不是 Table 的表。


问题和建议不仅限于Tables,所有数据库对象都需要标识符,包括SchemaViews 以及存在的许多类型、标准的和特定于供应商的。

另一种好的做法是在Table 标识符前面加上Schema 标识符,这对查询引擎有一点帮助。 当包含Schema 标识符时,标识符应该是合格的,

对于(MS SQL Server)TSQL使用方括号

SELECT * FROM [dbo].[Table];

对于 MySQL 使用 `

SELECT * FROM `dbo`.`Table`;

对于 Oracle、PostgreSQL 和 SQLite使用引号

SELECT * FROM "dbo"."Table";

即使您的Schema 不是以关键字命名的,也应该如此。


供您参考,帮助您避免冲突。

TSQL Reserverd Keywords 的列表。

MySQl Reserved Keywords 的列表。

Oracle Reserved Keywords 的列表。

SQLite Reserved Keywords 的列表。

PostgreSQL Reserved Keywords 的列表。

值得注意的“陷阱”包括USERERROR,它们似乎在设计系统时出现。

脚注:

在某些情况下,使用保留词作为对象名称可能在语义上是正确的。

考虑一个人为设计的家具店信息系统示例。在这种情况下,一张桌子(厨房、花园、餐厅、药剂师等)可能是正确的。因此,您可以争辩 Table 是正确的标识符。

如果你总是使用标识符限定符,你就不会被烧毁。

【讨论】:

  • 谢谢!但只是重命名表也有效;)
【解决方案2】:

如果您使用的是 SQL Server,则需要将表括在括号 [] 中,因为 table 是 SQL Server 中的关键字

SELECT * FROM [Table]

【讨论】:

  • 为什么投反对票?这是第一个答案,而且是正确的。
  • 我认为它不值得一票否决,但如果它在另一个答案中包含“为什么”部分会很好。
  • 不是我的反对票,但我猜反对票是因为这已经在评论中得到了回答
  • 不,否决票是因为不清楚是否使用了 MSSQL,并且 2. 这不是要走的路。重命名表。但是所有这些都已经在 cmets 中讨论过了。所以在我看来,你的答案是错误的,也是过时的。
猜你喜欢
  • 2021-12-13
  • 1970-01-01
  • 1970-01-01
  • 2017-03-16
  • 1970-01-01
  • 1970-01-01
  • 2018-04-21
  • 2018-10-15
  • 1970-01-01
相关资源
最近更新 更多