How can I use a column named _id from a dashDB table? - sql

I have a database in Cloudant where the document ID is _id.
After replicating this data from Cloudant to dashDB I have 2 separate tables that I want to join using this _id column. In Run SQL I tried the below, but this would not run. What am I missing here? Do I need to replace the column name _id to something without an underscore?
select m.title, m.year, g.value
from MOVIES m
inner join MOVIES_GENRE g on m._ID = g._ID;

TL;DR: As #gmiley points out the issue is caused by the _ID column name, which is not an ordinary identifier (see definition below) and therefore needs to be enclosed in double quotes "_ID" or single quotes '_ID' in your SQL statements.
select m.title, m.year, g.value
from MOVIES m
inner join MOVIES_GENRE g on m."_ID" = g."_ID";
Unlike ordinary identifiers quoted identifiers are case sensitive ("_id" is not identical to "_ID" whereas title is identical to TITLE). If you were to specify "_id" in your statement an error would be raised indicating that the column wasn't found.
Since you've mentioned that you've used the Cloudant warehousing process to populate your DashDB tables it's probably worth mentioning that property names are upper-cased when the DDL is generated during the schema discovery.
Example: The content of JSON documents with this structure
{
"_id": "000018723bdb4f2b06f830f676cfafd6",
"_rev": "1-91f98642f125315b929be5b5436530e7",
"date_received": "2016-12-04T17:46:47.090Z",
...
}
will be mapped to three columns:
_ID of type VARCHAR(...)
_REV of type VARCHAR(...)
DATE_RECEIVED of type ...
...
Hope this helps!
From the DB2 SQL reference:
An ordinary identifier is an uppercase letter followed by zero or more characters, each of which is an uppercase letter, a digit, or the underscore character. Note that lowercase letters can be used when specifying an ordinary identifier, but they are converted to uppercase when processed. An ordinary identifier should not be a reserved word.
Examples: WKLYSAL WKLY_SAL
A delimited identifier is a sequence of one or more characters enclosed by
double quotation marks. Leading blanks in the sequence are significant.
Trailing blanks in the sequence are not significant, although they are stored
with the identifier. Two consecutive quotation marks are used to represent
one quotation mark within the delimited identifier. In this way an identifier
can include lowercase letters.
Examples:
"WKLY_SAL" "WKLY SAL" "UNION" "wkly_sal"

Related

I am unable to drop a column from DB2 table

I am trying to drop a column from my DB2 table.
Table name = Instructor
Column name is Page
Command used is:
ALTER TABLE instructor
DROP COLUMN page;
I am getting this error
Column, attribute, or period "PAGE" is not defined in "GFQ70186.INSTRUCTOR".. SQLCODE=-205, SQLSTATE=42703, DRIVER=4.25.1301
Please help me to understand this error
If your column name is Page (i.e. with a capital P and lower case age) then you will need to use double quotes
ALTER TABLE INSTRUCTOR
DROP COLUMN "Page"
https://www.ibm.com/support/knowledgecenter/en/SSEPGG_11.5.0/com.ibm.db2.luw.sql.ref.doc/doc/r0000720.html
Ordinary identifier:
An ordinary identifier is an uppercase letter followed by zero or more characters, each of which is an uppercase letter, a digit, or the underscore character. Note that lowercase letters can be used when specifying an ordinary identifier, but they are converted to uppercase when processed
Delimited identifier:
A delimited identifier is a sequence of one or more characters enclosed by double quotation marks. Leading blanks in the sequence are significant. A delimited identifier can be used when the sequence of characters does not qualify as an ordinary identifier. In this way an identifier can include lowercase letter

Column isn't being found?

I am trying to display the username, last name, join date and country name for all the users who joined after the 13th January 2017 in ascending order. However each time I try to call any column, I get the error message "Column: Invalid Identifier".
SELECT Username, LastName, JoinDate, CountryName
FROM BR_USER, BR_COUNTRY
WHERE JoinDate = '01-JAN-17' AND JoinDate IS NOT NULL
ORDER BY JoinDate ASC;
Here is an image of how the BR_USER table is created.
Simple codes like:
SELECT UserId
FROM BR_USER;
Gives the same invalid identifier error, help
As the documentation explains:
Every database object has a name. In a SQL statement, you represent the name of an object with a quoted identifier or a nonquoted identifier.
A quoted identifier begins and ends with double quotation marks ("). If you name a schema object using a quoted identifier, then you must use the double quotation marks whenever you refer to that object.
If you define a column name with double quotes, you are condemned to using the double quotes whenever your reference that column. Or table or anything else with a name.
Actually, I don't think the documentation is 100% correct. Oracle uppercases all identifiers for resolution. So, if you define a quoted identifier with all upper case, then it will work without quotes. So this works:
create table t (
"COL" int
);
select "COL", COL, col
from t;
Here is a db<>fiddle.
But who wants to remember such rules -- rules so arcane and complex that the documentation is even misleading.
Simple solution: Don't use double quotes.

Are PostgreSQL column names case-sensitive?

I have a db table say, persons in Postgres handed down by another team that has a column name say, "first_Name". Now am trying to use PG commander to query this table on this column-name.
select * from persons where first_Name="xyz";
And it just returns
ERROR: column "first_Name" does not exist
Not sure if I am doing something silly or is there a workaround to this problem that I am missing?
Identifiers (including column names) that are not double-quoted are folded to lowercase in PostgreSQL. Column names that were created with double-quotes and thereby retained uppercase letters (and/or other syntax violations) have to be double-quoted for the rest of their life:
"first_Name"
Values (string literals / constants) are enclosed in single quotes:
'xyz'
So, yes, PostgreSQL column names are case-sensitive (when double-quoted):
SELECT * FROM persons WHERE "first_Name" = 'xyz';
Read the manual on identifiers here.
My standing advice is to use legal, lower-case names exclusively so double-quoting is never required.
To quote the documentation:
Key words and unquoted identifiers are case insensitive. Therefore:
UPDATE MY_TABLE SET A = 5;
can equivalently be written as:
uPDaTE my_TabLE SeT a = 5;
You could also write it using quoted identifiers:
UPDATE "my_table" SET "a" = 5;
Quoting an identifier makes it case-sensitive, whereas unquoted names are always folded to lower case (unlike the SQL standard where unquoted names are folded to upper case). For example, the identifiers FOO, foo, and "foo" are considered the same by PostgreSQL, but "Foo" and "FOO" are different from these three and each other.
If you want to write portable applications you are advised to always quote a particular name or never quote it.
The column names which are mixed case or uppercase have to be double quoted in PostgresQL. So best convention will be to follow all small case with underscore.
if use JPA I recommend change to lowercase schema, table and column names, you can use next intructions for help you:
select
psat.schemaname,
psat.relname,
pa.attname,
psat.relid
from
pg_catalog.pg_stat_all_tables psat,
pg_catalog.pg_attribute pa
where
psat.relid = pa.attrelid
change schema name:
ALTER SCHEMA "XXXXX" RENAME TO xxxxx;
change table names:
ALTER TABLE xxxxx."AAAAA" RENAME TO aaaaa;
change column names:
ALTER TABLE xxxxx.aaaaa RENAME COLUMN "CCCCC" TO ccccc;
You can try this example for table and column naming in capital letters. (postgresql)
//Sql;
create table "Test"
(
"ID" integer,
"NAME" varchar(255)
)
//C#
string sqlCommand = $#"create table ""TestTable"" (
""ID"" integer GENERATED BY DEFAULT AS IDENTITY primary key,
""ExampleProperty"" boolean,
""ColumnName"" varchar(255))";

Force identifier case sensitivity in oracle

In oracle, when one uses non-quoted identifiers, they are silently capitalized. In other words these two statements are equivalent:
SELECT name FROM my_table
SELECT "NAME" FROM "MY_TABLE"
Is there any way to stop the silent capitalization, so that the following statements become equivalent?
SELECT name FROM my_table
SELECT "name" FROM "my_table"
No, unfortunately you can't customize how Oracle interprets your identifiers:
Note that Oracle interprets the following names the same, so they cannot be used for different objects in the same namespace:
employees
EMPLOYEES
"EMPLOYEES"
It is a convenience (backward compatibility?) that non-quoted identifiers are converted to upper-case (internally all object names are case-sensitive).

[] brackets in sql statements

What do the brackets do in a sql statement?
For example, in the statement:
insert into table1 ([columnname1], columnname2) values (val1, val2)
Also, what does it do if the table name is in brackets?
The [] marks the delimitation of a identifier, so if you have a column whose name contains spaces like Order Qty you need to enclose it with [] like:
select [Order qty] from [Client sales]
They are also to escape reserved keywords used as identifiers
This is Microsoft SQL Server nonstandard syntax for "delimited identifiers." SQL supports delimiters for identifiers to allow table names, column names, or other metadata objects to contain the following:
SQL reserved words: "Order"
Words containing spaces: "Order qty"
Words containing punctuation:
"Order-qty"
Words containing international
characters
Column names that are
case-sensitive: "Order" vs. "order"
Microsoft SQL Server uses the square brackets, but this is not the syntax standard SQL uses for delimited identifiers. Standardly, double-quotes should be used for delimiters.
In Microsoft SQL Server, you can enable a mode to use standard double-quotes for delimiters as follows:
SET QUOTED_IDENTIFIER ON;
They are meant to escape reserved keywords or invalid column identifiers.
CREATE TABLE test
(
[select] varchar(15)
)
INSERT INTO test VALUES('abc')
SELECT [select] FROM test
They allow you to use keywords (such as date) in the name of the column, table, etc...
Since this is a bad practice to begin with, they are generally not included. The only place you should see them being used is by people starting out with sql queries that don't know any better. Other than that they just clutter up your query.
Anything inside the brackets is considered a single identifier (e.g. [test machine]. This can be used to enclose names with spaces or to escape reserve words (e.g. [order], [select], [group]).
if you use any column name which is same as any reserved keyword in sql, in that case you can put the column name in square bracket to distinguish between your custom column name and existing reserved keyword.
When having table names or filenames with spaces or dashes (-) etc... you can receive "Systax error in FROM clause".
Use [] brackets to solve this.
See: https://msdn.microsoft.com/en-us/library/ms175874.aspx
They are simply delimiters that allow you to put special characters (like spaces) in the column or table name
e.g.
insert into [Table One] ([Column Name 1], columnname2) values (val1, val2)