If my query is
SELECT from FROM myTable;
How can I escape column name 'from'.
I need a way which is applicable to Oracle, MySQL, Teradata and all other systems
Will
SELECT myTable.from FROM mytable;
work on all systems?
The SQL standard is pretty clear: reserved keywords can only be used when they are enclosed in double quotes:
select "FROM" from mytable;
Note that a quoted identifier are also case sensitive. "Foo" and "FOO" are two different names! (whereas Foo and FOO are the same names in standard SQL and most DBMS)
I need a way which is applicable to Oracle, MySQL, Teradata and all other systems
Postgres, Oracle, DB2 (LUW), Firebird, Ingres, HSQLDB, H2, Vertica, HANA and Teradata comply with the standard out of the box.
MySQL needs to convinced to respect the standard by setting sql-mode to ANSI or at least ANSI_QUOTES.
For SQL Server the option QUOTED_IDENTIFIER needs to be set to on.
For Informix you need to set DELIMIDENT to y when connecting through JDBC
But in general you should really avoid the need to use quoted identifiers. Typically you will get in trouble sooner or later by doing that.
Universal method??? not sure about any such but double quote "" is ANSI standard other than that every RDBMS has some specific way of doing so. Moreover you don't need any such universal way if you refrain yourself from using reserve word or keyword for table or column name .. as already suggested in comment
Related
Do any SQL databases have case-sensitive naming for field names?
What I mean is, in Java you can have two variables ...
String fieldname = "a";
String fieldName = "b";
Are there any SQL databases support that so ...
SELECT fieldname, fieldName FROM MY_TABLE;
... would return two different columns?
I'm asking because I'm building a database utility that has to work for MySQL, H2, PostgreSQL, Oracle, and SQL Server, so I need to know how they all work for a bit of code I'm writing.
In most databases (and in all those you tagged), an unquoted identifier is case-insensitive. Meaning that fieldname and fieldName are the same thing: the database folds them into the default case, which makes them equivalent.
In most databases, you can make an identifier case-sensitive by quoting it. The quoting character varies across databases. In standard SQL, you use double quotes. So "fieldname" and "fieldName" are two different things. Oracle and Postgres follow that standard. SQL Server wants square brackets ([]); MySQL wants backticks.
In a nutshell: in SQL, I would not recommend using case-sensitive identifiers. This makes things more complicated for no value added. In my opinion, snake case style is your best pick in SQL, because upper/lower case are meaningless.
By the SQL standard, SQL identifiers are case-insensitive. So, without escape characters, these refer to the same column:
select fieldname, fieldName
However, you can escape the names and they become distinguishable. The standard SQL escape character is ":
select "fieldname", "fieldName"
But some databases don't support this and have their own.
In Oracle, you can certainly have case-sensitive column names, they just need to be quoted. So this query would return data from three separate columns
SELECT "columnName", "ColumnName", columnName
FROM table
In SQL Server, you can have case-sensitive columns but they need to be enclosed in brackets, i.e.
SELECT [ColumnName], [columnName], [columnname]
FROM table
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've got a strange problem. A customer named a field in FirebirdSQL start. Now I cannot select this field:
select t.start from table t
Gives me the error: Invalid token
Any idea on how I can select this field?
The word start is a reserved word in Firebird and therefor needs to be quoted. The quote symbol in Firebird is the double quote. So you need to use:
select t."start" from "table" t
Note that I quoted table as well, as it is also a reserved word. Quoting makes the name case sensitive, so you may need to use "START" and "TABLE".
In your comments you mention that quoting yields a constant value 'table'. This means that you are using dialect 1, the deprecated (and legacy) dialect of Firebird. This legacy dialect cannot quote object names, and the double quote is for string literals (next to the SQL standard single quotes). Either your database is a dialect 1 database, or you specified the wrong connection dialect in your connection library.
If you database is actually dialect 3, solving this is as simple as specifying connection dialect 3 (or 0 to auto select based on the database dialect). However if your database is a dialect 1 database you will need to migrate to dialect 3 to be able to solve this.
If this is simply to try things out: make sure you create a dialect 3 database (for most tools this is the default).
How to determine database dialect
To determine the database dialect, you can use the gstat tool:
gstat mydatabase.fdb -header
In recent Firebird versions you can also query the MON$DATABASE monitoring table. Most query tools also allow you to view the database properties.
How to migrate from dialect 1 to dialect 3
That is I think too complicated to write down here (and I have never done it myself as it was considered deprecated years ago). However the Interbase 6.0 Getting Started (available from Firebird: Reference Manuals (at the end of the page) describes the basic process of migration, and I am sure that there are pages to be found with some googling.
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]