简体   繁体   English

简单的SELECT语句失败,“语法使用附近”,“ORA-00906”,“语法错误在或附近”或“语法在关键字附近”

[英]Simple SELECT statement fails with “syntax to use near”, “ORA-00906”, “syntax error at or near” or “syntax near the keyword”

I have a very simple SQL statement 我有一个非常简单的SQL语句

SELECT * FROM Table;

but, my query engine returns a syntax error. 但是,我的查询引擎返回语法错误。 Why? 为什么?

Error Details: 错误详情:

An unhandled exception of type 'System.Data.SqlClient.SqlException' occurred in >System.Data.dll > System.Data.dll中出现未处理的“System.Data.SqlClient.SqlException”类型的异常

Additional information: Incorrect syntax near the keyword 'Table'. 附加信息:关键字“表”附近的语法不正确。

How is this possible? 这怎么可能? I checked the connection string and it is correct. 我检查了连接字符串,这是正确的。 I checked my table name and it is also correct. 我检查了我的表名,这也是正确的。

What I am doing wrong? 我做错了什么?

Okay, Table is a reserved keyword in all variants of SQL. 好的, Table是SQL的所有变体中的保留关键字。

If you want to call a table Table , and use it in a statement, you have to tell your sql engine that it is an identifier. 如果要调用表Table ,并在语句中使用它,则必须告诉sql引擎它是一个标识符。 To do this you need to use Identifier Qualifiers . 为此,您需要使用标识符限定符

for (MS SQL Server) TSQL use square brackets for(MS SQL Server)TSQL使用方括号

SELECT * FROM [Table];

for MySQL use ` 对于MySQL使用`

SELECT * FROM `Table`;

for Oracle and PostgreSQL use quotation marks, these are standards compliant. 对于Oracle和PostgreSQL使用引号,这些符合标准。

SELECT * FROM "Table";

for SQLite you can use any of the above, but quotation marks are prefered. 对于SQLite,您可以使用上述任何一种,但首选引号。

The Identifier Qualifiers tell the engine that this is an identifier (the name of an object.) Not the name of a keyword, even if they happen to be the same. 标识符限定符告诉引擎这是一个标识符(对象的名称。)不是关键字的名称,即使它们碰巧是相同的。 Without your guidance the query engine can get confused and report an error, or worse, do something unexpected. 如果没有您的指导,查询引擎可能会混淆并报告错误,或者更糟糕的是,执行意外操作。

Using Identifier Qualifiers is good practice , even if the identifers are not keywords. 使用标识符限定符是一种很好的做法 ,即使标识符不是关键字也是如此。 They better define statements for all parsers, including the fleshy kind. 他们更好地为所有解析器定义语句,包括肉类。

Naming objects after keywords is generally considered bad practice. 在关键字之后命名对象通常被认为是不好的做法。 So you should try to avoid making identifers the same as keywords. 因此,您应该尽量避免使标识符与关键字相同。 The occasions when a reserved keyword is descriptive of the contents of a table are rare, see the footnote. 保留关键字描述表格内容的情况很少见,请参阅脚注。

eg your table is not a Table of tables. 例如,您的表不是Table表。


The problem and advice is not limited to Tables , Identifiers are required for all database objects inluding Schema , Views and the many types that exist, standard and vendor-specific. 问题和建议不仅限于Tables ,所有数据库对象都需要标识符,包括SchemaViews以及存在的许多类型,标准和特定于供应商。

Another form of good practice is to prefix Table indentifiers with a Schema identifier, this helps the query engine a little. 另一种形式的良好实践是为Table标识符添加Schema标识符,这有助于查询引擎。 When including the Schema identifier, the identifer should be qualified, 包含Schema标识符时,标识符应该是合格的,

for (MS SQL Server) TSQL use square brackets for(MS SQL Server)TSQL使用方括号

SELECT * FROM [dbo].[Table];

for MySQL use ` 对于MySQL使用`

SELECT * FROM `dbo`.`Table`;

for Oracle, PostgreSQL and SQLite use quotation marks 对于Oracle,PostgreSQL和SQLite使用引号

SELECT * FROM "dbo"."Table";

even if your Schema is not named after a keyword, as should be the case. 即使你的Schema没有以关键字命名,也应如此。


For your reference, to help you avoid conflicts. 供您参考,以帮助您避免冲突。

A list of TSQL Reserverd Keywords . TSQL Reserverd关键字列表。

A list of MySQl Reserved Keywords . MySQl保留关键字列表。

A list of Oracle Reserved Keywords . Oracle保留关键字列表。

A list of SQLite Reserved Keywords . SQLite保留关键字列表。

A list of PostgreSQL Reserved Keywords . PostgreSQL保留关键字列表。

Notable "gotcha's" include USER and ERROR , which seem to come up when designing systems. 值得注意的“问题”包括USERERROR ,它们似乎在设计系统时出现。

Footnote: 脚注:

There are occasions when using reseved words for object names may be semantically correct. 在某些情况下,对象名称使用重新学习的单词可能在语义上是正确的。

Consider the contrived example of an information system for a furniture shop. 考虑一个家具店信息系统的人为例子。 In this scenario, a table of tables (kitchen, garden, dining, apothecary etc.) may be correct. 在这种情况下,表格(厨房,花园,餐厅,药剂师等)可能是正确的。 So, you could argue Table was the correct identifier. 所以,你可以说Table是正确的标识符。

If you always use Identifier Qualifiers, you won't get burned. 如果您始终使用标识符限定符,则不会被刻录。

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

SELECT * FROM [Table]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM