I have a table with a field named COMMENT, which appears to be a reserved word.
Using SQLDeveloper, if I try:
select
[COMMENT],
another_field
FROM table_created_by_idiot_developer
I get
SQL Error: ORA-00936: missing expression
How can I access this field in my select in SQL Developer? (Is this a problem with SQL Developer, or should field not be named COMMENT in oracle?)
Try "COMMENT" instead of [COMMENT]. This is alternate syntax commonly accepted by various DBMSes. I have used this syntax to refer to columns having dots or UTF8 characters in their names in SQLite.
Related
This question's answers are a community effort. Edit existing answers to improve this post. It is not currently accepting new answers or interactions.
I'm trying to execute a simple MySQL query as below:
INSERT INTO user_details (username, location, key)
VALUES ('Tim', 'Florida', 42)
But I'm getting the following error:
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'key) VALUES ('Tim', 'Florida', 42)' at line 1
How can I fix the issue?
The Problem
In MySQL, certain words like SELECT, INSERT, DELETE etc. are reserved words. Since they have a special meaning, MySQL treats it as a syntax error whenever you use them as a table name, column name, or other kind of identifier - unless you surround the identifier with backticks.
As noted in the official docs, in section 10.2 Schema Object Names (emphasis added):
Certain objects within MySQL, including database, table, index, column, alias, view, stored procedure, partition, tablespace, and other object names are known as identifiers.
...
If an identifier contains special characters or is a reserved word, you must quote it whenever you refer to it.
...
The identifier quote character is the backtick ("`"):
A complete list of keywords and reserved words can be found in section 10.3 Keywords and Reserved Words. In that page, words followed by "(R)" are reserved words. Some reserved words are listed below, including many that tend to cause this issue.
ADD
AND
BEFORE
BY
CALL
CASE
CONDITION
DELETE
DESC
DESCRIBE
FROM
GROUP
IN
INDEX
INSERT
INTERVAL
IS
KEY
LIKE
LIMIT
LONG
MATCH
NOT
OPTION
OR
ORDER
PARTITION
RANK
REFERENCES
SELECT
TABLE
TO
UPDATE
WHERE
The Solution
You have two options.
1. Don't use reserved words as identifiers
The simplest solution is simply to avoid using reserved words as identifiers. You can probably find another reasonable name for your column that is not a reserved word.
Doing this has a couple of advantages:
It eliminates the possibility that you or another developer using your database will accidentally write a syntax error due to forgetting - or not knowing - that a particular identifier is a reserved word. There are many reserved words in MySQL and most developers are unlikely to know all of them. By not using these words in the first place, you avoid leaving traps for yourself or future developers.
The means of quoting identifiers differs between SQL dialects. While MySQL uses backticks for quoting identifiers by default, ANSI-compliant SQL (and indeed MySQL in ANSI SQL mode, as noted here) uses double quotes for quoting identifiers. As such, queries that quote identifiers with backticks are less easily portable to other SQL dialects.
Purely for the sake of reducing the risk of future mistakes, this is usually a wiser course of action than backtick-quoting the identifier.
2. Use backticks
If renaming the table or column isn't possible, wrap the offending identifier in backticks (`) as described in the earlier quote from 10.2 Schema Object Names.
An example to demonstrate the usage (taken from 10.3 Keywords and Reserved Words):
mysql> CREATE TABLE interval (begin INT, end INT);
ERROR 1064 (42000): You have an error in your SQL syntax.
near 'interval (begin INT, end INT)'
mysql> CREATE TABLE `interval` (begin INT, end INT);
Query OK, 0 rows affected (0.01 sec)
Similarly, the query from the question can be fixed by wrapping the keyword key in backticks, as shown below:
INSERT INTO user_details (username, location, `key`)
VALUES ('Tim', 'Florida', 42)"; ^ ^
This Statement:
SELECT id, units, cost FROM inventory_list WHERE cost <= 20;
Gives me:
ORA-00923: FROM keyword not found where expected
While this statement:
SELECT * FROM items WHERE ilt_id = 'il010230126' OR ilt_id = 'il010230128';
Gives me:
ORA-00933: SQL command not properly ended
Not sure about this and may be version dependent (below link is for oracle 10g... but you can see on this site
https://docs.oracle.com/cd/B19306_01/em.102/b40103/app_oracle_reserved_words.htm
That cost is an oracle reserved keyword, so it is not wise to use it as a column name.
If you have no control of the table I think you may be able to surround it in double quotes eg select "COST" to avoid oracle picking it up as a reserved word.
By default Oracle creates fields in uppercase so the field name will need to be in uppercase unless when the table was created it was forced into different case by surrounding it in Quotes.
Check that you don't have invisible characters in your file and that you're using the right encoding. I sometimes accidentally introduce them because I have a non english keyboard map and accidentally hit the wrong key combination.
Just type again one of your SQL statements and test them.
I am trying to do a query in a SQLite database equivalent to this:
SELECT act_unit FROM processes WHERE process='processname'
but using the keyword values, so I can specify the name, which is stored in a variable (I am actually running the query in a Jupyter notebook). I've used successfully the keyword values in insert statements, but I do not know how to do it here. I tried several combinations like this one
SELECT act_unit from processes WHERE process=values,('processname')
but I can't figure out how to do it properly.
From the SQLite documentation: https://www.sqlite.org/lang_keywords.html
It would be SELECT act_unit from processes WHERE process="values",('processname')
If you want to use a keyword as a name, you need to quote it. There
are four ways of quoting keywords in SQLite:
'keyword' A keyword in single quotes is a string literal.
"keyword" A keyword in double-quotes is an identifier.
[keyword] A
keyword enclosed in square brackets is an identifier. This is not
standard SQL. This quoting mechanism is used by MS Access and SQL
Server and is included in SQLite for compatibility.
keyword A
keyword enclosed in grave accents (ASCII code 96) is an identifier.
This is not standard SQL. This quoting mechanism is used by MySQL and
is included in SQLite for compatibility.
I have table named References in SQLite, so I can't target it, it seems. SQLite studio I use to edit databases throws an error.
Is there a way to escape database name?
The query is:
UPDATE References
SET DateTimeLastEdited = datetime('now', 'localtime')
WHERE NewsItemID = old.NewsItemID;
(This is part of the trigger I am making.)
You can escape table names with double quotes:
UPDATE "References" SET DateTimeLastEdited = datetime('now', 'localtime') WHERE NewsItemID = old.NewsItemID;
Depending on what you want to escape, you need to use different delimiters:
If you want to use a keyword as a name, you need to quote it. There
are four ways of quoting keywords in SQLite:
'keyword' A keyword in single quotes is a string literal.
"keyword" A keyword in double-quotes is an identifier.
[keyword] A
keyword enclosed in square brackets is an identifier. This is not
standard SQL. This quoting mechanism is used by MS Access and SQL
Server and is included in SQLite for compatibility.
`keyword` A
keyword enclosed in grave accents (ASCII code 96) is an identifier.
This is not standard SQL. This quoting mechanism is used by MySQL and
is included in SQLite for compatibility.
From SQLite documentation
I have a very simple SQL statement
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
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.
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. To do this you need to use Identifier Qualifiers.
for (MS SQL Server) TSQL use square brackets
SELECT * FROM [Table];
for MySQL use `
SELECT * FROM `Table`;
for Oracle and PostgreSQL use quotation marks,
these are standards compliant.
SELECT * FROM "Table";
for SQLite you can use any of the above, but quotation marks are prefered.
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.
e.g. your table is not a Table of tables.
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.
Another form of good practice is to prefix Table indentifiers with a Schema identifier, this helps the query engine a little.
When including the Schema identifier, the identifer should be qualified,
for (MS SQL Server) TSQL use square brackets
SELECT * FROM [dbo].[Table];
for MySQL use `
SELECT * FROM `dbo`.`Table`;
for Oracle, PostgreSQL and SQLite use quotation marks
SELECT * FROM "dbo"."Table";
even if your Schema is not named after a keyword, as should be the case.
For your reference, to help you avoid conflicts.
A list of TSQL Reserverd Keywords.
A list of MySQl Reserved Keywords.
A list of Oracle Reserved Keywords.
A list of SQLite Reserved Keywords.
A list of PostgreSQL Reserved Keywords.
Notable "gotcha's" include USER and ERROR, which seem to come up when designing systems.
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.
If you always use Identifier Qualifiers, you won't get burned.
If you are using SQL server you need to wrap table in brackets [] as table is keyword in SQL Server
SELECT * FROM [Table]