One can use delimited identifier in JDBC query and it works with below databases even for a non reserved keyword with below delimiters:
SQLServer: Square bracket => [select]
Postgres, Teradata, Oracle, Sybase and DB2: double quote => "select"
For Netezza I tried single quote as per documentation, but it did not work.
https://www.ibm.com/support/knowledgecenter/en/SSULQD_7.2.1/com.ibm.nz.dbu.doc/c_dbuser_quoted_mixed_literals.html
Please suggest.
What works at my site is the " (double quotes) around table/column names containing reserved words, spaces, special/national characters, numbers at the beginning and many other things a good data model does not contain (opinion - I know, but a heart felt one)
You need to be aware that anything referenced using "surrounding", becomes cAsE sensitive.
Try querying the catalog view INFORMATION_SCHEMA.COLUMNS using your favorite sql-client (aginity?) and look carefully at the caSiNg etc of the names of the columns/table you try to reference.
Hope this helps - otherwise please post a simple piece of sql that you would expect to succeed, along with the error message you got back, just as ScottMcG suggested
Related
I multiple tables in my database. All of my tables are showing output using select query instead of only 1 table "case". it also have data and columns but when I use it in my query it shows syntax error. I have also attached picture which have list of table and a simple query. This code is not developed by me so I am not sure why it is showing error. Is there any kind of restriction we can set so that it cannot be used in queries?
CASE is a reserved keyword in SQL Server. Therefore, you must escape it in double brackets:
SELECT * FROM dbo.[Case];
But best naming practice dictates that we should avoid naming database objects using reserved keywords. So, don't name your tables CASE.
Reserved words are not recommended for use as a database, table, column, variable, or other object names. If you desire to use a reserved word is used as an object name in ANSI standard syntax, it must be enclosed in double-quotes OR "[]" to allow the Relational Engine (whichever that one is) that the word is being used as an object and not as a keyword in the given context. Here is the sample code.
SELECT * FROM dbo."Case"
Or
SELECT * FROM dbo.[Case]
I have oracle express installation, and by default it is case insensitive ( table creation/ keys name ). I want to change it to case sensitive. Is there a configuration to do so?
There is no setting, no.
In any version of Oracle, however, you can use case-sensitive identifiers by enclosing them in double-quotes.
create table "CamelCase" (
"ColumnName1" integer
);
will create a table CamelCase which is case-sensitive and a column ColumnName1 that is case sensitive. In order to use the column, though, every reference will need to be surrounded in double-quotes
SELECT "ColumnName1"
FROM "CamelCase"
would work. However
SELECT ColumnName1
FROM CamelCase
would not.
Using case-sensitive identifiers is generally a really bad idea so I would strongly suggest that you don't do so. It is an option though.
No, there is no configuration for that. You can't make identifiers case-sensitive without quoting them, but Oracle recommends against using quoted identifiers:.
Oracle does not recommend using quoted identifiers for database object names. These quoted identifiers are accepted by SQL*Plus, but they may not be valid when using other tools that manage database objects.
And even then if you have a quoted identifier that is all-caps anyway, e.g. "MY_TABLE", that is treated the same as an unquoted identifier so you can still refer to it as my_table, which might not be case-sensitive enough for you. Anything mixed-case or with invalid characters always has to be referred to quoted though, e.g. `select * from "My Table", which makes code harder to read and maintain (in my opinion anyway).
I'd really recommend not doing this. Anyone having to maintain your schema or code will not thank you for it.
Is there any option to set the words "file", "key" and "trigger" as field names for ms-sql server?
We have pretty big application written with web2py with PostgreSQL as db, ans some of the fields has those names. One customer wishes to use ms-sql as db server, And I'm trying not to break compatibility within the DB structure.
Using square brackets (found in google) didn't help (could not use '[file]') - the ms-sql rejected it.
The documentation is pretty clear on this:
Although it is syntactically possible to use SQL Server reserved
keywords as identifiers and object names in Transact-SQL scripts, you
can do this only by using delimited identifiers.
The delimiters used in SQL Server are either double quotes or []. So, you can define them as:
[file]
or
"file"
Note that you need to use the delimiters wherever they appear.
The use of reserved words for such columns is discouraged. However, you might actually have a use case of compatibility between different databases where this capability will be useful.
I don't know why square bracket would fail. It works on SQL Fiddle.
I stumbled into this same issue when trying to use a legacy SQL Server table with fields that don't conform to identifier name rule, such as 'My File'.
Reading the source code I found that a rname field attribute exists for these cases:
Field('my_file', 'string', rname='[My File]'),
With this, Web2Py works with the my_file field name, the actual SQL/DML generated to interact with the database will use [My File] instead.
The DB I use has French_CI_AS collation (CI should stand for Case-Insensitive) but is case-sensitive anyway. I'm trying to understand why.
The reason I assert this is that bulk inserts with a 'GIVEN' case setup fail, but they succeed with another 'Given' case setup.
For example:
INSERT INTO SomeTable([GIVEN],[COLNAME]) VALUES ("value1", "value2") fails, but
INSERT INTO SomeTable([Given],[ColName]) VALUES ("value1", "value2") works.
EDIT
Just saw this:
http://msdn.microsoft.com/en-us/library/ms190920.aspx
so that means it should be possible to change a column's collation without emptying all the data and recreating the related table?
Given this critical piece of information (that is in a comment on the question and not in the actual question):
In fact I use Microsoft .Net's bulk insert method, so I don't really know the exact query it sends to the DB server.
it makes sense that the column names are being treated as case-sensitive, even in a case-insensitive DB, since that is how the SqlBulkCopy Class works. Please see Column mappings in SqlBulkCopy are case sensitive.
ADDITIONAL NOTES
When asking about an error, please always include the actual, and full, error message in the question. Simply saying that there was an error leads to a lot of guessing and wild-goose chases that in turn lead to off-topic answers.
When asking a question, please do not change the circumstances that you are dealing with. For example, the question states (emphasis added):
bulk inserts with a 'GIVEN' case setup fail, but they succeed with another 'Given' case setup.
Yet the example statements are single INSERTs. Also, a comment on the question states:
In fact I use Microsoft .Net's bulk insert method, so I don't really know the exact query it sends to the DB server.
Using .NET and SqlBulkCopy is waaaay different than using BULK INSERT or INSERT, making the current question misleading, making it difficult (or even impossible) to answer correctly. This new bit of info also leads to more questions because when using SqlBulkCopy, you don't write any INSERT statements: you just write a SELECT statement and specify the name of the destination Table. If you specify column names at all for the destination Table, it is in the optional column mappings. Is that where the issue is?
Regarding the "EDIT" section of the question:
No, changing the Collation of the column won't help at all, even if you weren't using SqlBulkCopy. The Collation of a column determines how data stored in the column behaves, not how the column names (i.e. meta-data of the Table) behaves. It is the Collation of the Database itself that determines how Database-level object meta-data behaves. And in this case, you claim that the DB is using a case-insensitive Collation (correct, the _CI_ portion of the Collation name does mean "Case Insensitive").
Regarding the following statements made by Jonathan Leffler on the question:
that gets into a very delicate area of the interaction between delimited identifiers (normally case-sensitive) and collations (this one is case-insensitive).
No, delimited identifiers are not normally case-sensitive. The sensitivities (case, accent, kana type, width, and starting in SQL Server 2017 variation selector) of delimited identifiers is the same as for non-delimited identifiers at that same level. "Same level" means that Instance-level names (Databases, Logins, etc) are controlled by the Instance-level Collation, while Database-level names (Schemas, Objects--Tables, Views, Functions, Stored Procedures, etc--, Users, etc) are controlled by the Database-level Collation. And these two levels can have different Collations.
you need to research whether the SQL column names in a database are case-sensitive when delimited. It may also depend on how the CREATE TABLE statement is written (were the names delimited in that?). Normally, SQL is case-insensitive on column and table names; you could write INSERT INTO SoMeTaBlE(GiVeN, cOlNaMe) VALUES("v1", "v2") and if the names were never delimited, it'd be OK.
It does not matter if the column names were delimited or not when creating the Table, at least not in terms of how their resolution is handled. Column names are Database-level meta-data, and that is controlled by the default Collation of the Database. And it is the same for all Database-level meta-data within each Databases. You cannot have some column names being case-sensitive while others are case-insensitive.
Also, there is nothing special about Table and column names. They are Database-level meta-data just like User names, Schema names, Index names, etc. All of this meta-data is controlled by the Database's default Collation.
Meta-data (both Instance-level and Database-level) is only "normally" case-insensitive due to the default Collation suggested during installation being a case-insensitive Collation.
a 'delimited identifier' is a column name, table name, or something similar enclosed in double quotes, such as CREATE TABLE "table"(...)
It is more accurate to say that a delimited identifier is an identifier enclosed in whatever character(s) the DBMS in question has defined as its delimiters. And which particular characters are used for delimiters varies between the different DBMSs.
In SQL Server, delimited identifiers are enclosed in square brackets: [GIVEN]
While square brackets always work as delimiters for identifiers, it is possible to use double-quotes as delimiters IF you have the session-level property of QUOTED_IDENTIFIER set to ON (which is best to always do anyway).
There are arcane parts to SQL (and delimited identifier handling is one of them)
Well, delimited identifiers are actually quite simple. The whole point of delimiting an identifier is to effectively ignore the rules of regular (i.e. non-delimited) identifiers. But, in terms of regular identifiers, yes, those rules are rather arcane (mainly due to the official documentation being incomplete and incorrect). So, in order to take the mystery out of how identifiers in SQL Server actually work, I did a bunch of research and published the results here (which includes links to the research itself):
Completely Complete List of Rules for T-SQL Identifiers
For more info on Collations / Encodings / Unicode / ASCII, especially as they relate to Microsoft SQL Server, please visit:
Collations.Info
The fact the column names are case sensitive means that the MASTER database has been created using a case sensitive collation.
In the case I just had that lead me to investigate this, someone entered
Latin1_CS_AI instead of Latin1_CI_AS
When setting up SQL server.
Check the collation of the columns in your table definition, and the collation of the tempdb database (i.e. the server collation). They may differ from your database collation.
In SQL Server, why is this:
[dbo].[table_name]
preferable to this:
dbo.table_name
And along those lines, why even list the dbo at all if there's only one schema?
If the table name contains key words, you will have to enclose it inside [ ]. Most of the tools (like ORM) use this technique to avoid any errors or for consistency.
It's just in case you have a keyword as a tablename like [user]
It allows keywords or punctuation in a table name.
It's often used by code generators for all names, so they don't have to figure out if it actually needed.
These usually come up in generated code - because it's easier to make the code generation produce fully-qualified and escaped references than to deduce what escaping/qualification is required when.
If there is only one schema then prefixing the table name is not necessary or useful I think. Using the brackets [] is useful when you have an identifier that is a reserved word in sql server. If, for instance, you have a table named Select you can refernce it as SELECT * FROM [Select] but not as SELECT * FROM Select.
I don't use the brackets, which are only necessary if you use keywords as schemas or table names, which you shouldn't.
But I would recommend against dropping the dbo at the front. The reason is that eventually you might want to start organizing your code into schemas, and then you will need the prefix. If you get in the habit of using the schema.table format, it will be a lot easier to search your code for places where the tables are used.
Let's say you have a table called dbo.user, and you decide to move it to another schema. If you have to search through a bunch of stored procedures or dynamic sql for "user", you will likely get a ton of false positives. You can't be totally sure that you made all the changes you needed to. Searching for "dbo.user" is a lot more concise.
The [] are only required if the object name contains characters like spaces or if it is a keyword. It is generally regarded as best practice not to use any of these as object names so you should never need the []. Having said that they also do no harm, if it is generated code and includes the brackets then you may as well leave them.
Using dbo is a good idea becuase
Performance is better (see here for some figures)
dbo is required in some cases, like calling user defined functions. I think it is tidyer to always include it.
Not qualifying the object name could lead to bugs in the future if you do create multiple schemas.
Doesn't this allow you to have whatever 'bad' items you desire in there?
Keywords, spaces, etc...
I would prefer to avoid using punctuation and reserved words in table and column names, and not use the square brackets. This makes the SQL far easier to read.
Apart from spaces, reserved keywords, and system functions in an identifier name, an identifier can also contain some characters that are not allowed in regular identifiers, an it has to be separated with square brackets.
You can find a detailed explanation and rules for regular and delimited identifiers in this article.
From the article:
For example, delimited identifiers can contain spaces, any characters
valid for regular identifiers, and any one of the following
characters:
tilde (~) hyphen, (-) exclamation point (!), left brace ({), percent (%),
right brace (}), caret (^), apostrophe ('), ampersand (&), period (.), left
parenthesis ((), backslash (), right parenthesis ()), accent grave (`),
Using two name qualifying convention may improve performance (avoid name resolutions) and avoid ambiguity in cases when you have e.g. the same table name in two or more schema. In that case SQL Server will search your object in dbo and if it isn't there it will stop searching.
Also if you later want to use that object with the SCHEMABINDING option it doesn't allow unqualified object names.
Hope this helps