我有一个非常简单的SQL语句
SELECT * FROM Table;
但是,我的查询引擎返回语法错误。为什么呢?
错误详情:
类型' System.Data.SqlClient.SqlException'未处理的异常发生在> System.Data.dll
中其他信息:关键字'表'附近的语法不正确。
这怎么可能?我检查了连接字符串,这是正确的。 我检查了我的表名,这也是正确的。
我做错了什么?
答案 0 :(得分:11)
好的,Table
是所有SQL变种中的保留关键字。
如果要调用表Table
并在语句中使用它,则必须告诉sql引擎它是一个标识符。为此,您需要使用标识符限定符。
for(MS SQL Server)TSQL 使用方括号
SELECT * FROM [Table];
for MySQL 使用`
SELECT * FROM `Table`;
for Oracle和PostgreSQL 使用引号, 这些都符合标准。
SELECT * FROM "Table";
对于SQLite ,您可以使用上述任何一种,但最好使用引号。
标识符限定符告诉引擎这是一个标识符(对象的名称。)不是关键字的名称,即使它们碰巧是相同的。如果没有您的指导,查询引擎可能会混淆并报告错误,或者更糟糕的是,做一些意外的事情。
使用标识符限定符是一种良好做法,即使标识符不是关键字也是如此。 他们更好地为所有解析器定义语句,包括肉质类型。
在关键字之后命名对象通常被认为是不好的做法。因此,您应该尽量避免使标识符与关键字相同。保留关键字描述表格内容的情况很少见,请参阅脚注。
e.g。您的表格不是Table
个表格。
问题和建议不仅限于Tables
,所有数据库对象都需要标识符,包括Schema
,Views
以及存在的许多类型,标准和特定于供应商。< / p>
另一种良好做法是为Table
个标识符添加Schema
标识符,这有助于查询引擎。
在包含Schema
标识符时,标识符应该是合格的,
for(MS SQL Server)TSQL 使用方括号
SELECT * FROM [dbo].[Table];
for MySQL 使用`
SELECT * FROM `dbo`.`Table`;
for Oracle,PostgreSQL和SQLite 使用引号
SELECT * FROM "dbo"."Table";
即使您的Schema
未在关键字后命名,也应如此。
供您参考,以帮助您避免冲突。
PostgreSQL Reserved Keywords的列表。
值得注意的“陷阱”包括USER
和ERROR
,这些似乎在设计系统时出现。
脚注:
在某些情况下,对象名称使用重新学习的单词可能在语义上是正确的。
考虑一个家具店信息系统的人为例子。在这种情况下,表格(厨房,花园,餐厅,药剂师等)可能是正确的。所以,你可以说Table
是正确的标识符。
如果您始终使用标识符限定符,则不会被刻录。
答案 1 :(得分:5)
如果您使用的是SQL Server,则需要将表包装在方括号[]中,因为table
是SQL Server中的关键字
SELECT * FROM [Table]