ORACLE/SQL: Wildcard literally in a column name - sql

I have a table in which a column name begins with a wildcard. So one of the column is named _Test_
How can I access this column?
select _TEST_ from Table
throws an error, as well as
select *
from Table
where _TEST_ = 123
I tried suggestions with "escape", using [_TEST_], or \_TEST\_ but nothing worked. I cannot change the table.
EDIT (Thanks to #Alex Poole) : select * from Table Where "_TEST_"=123 works. But select "_TEST_" from Table does not.

An underscore is only a wildcard for the like pattern-matching condition. In the context you are trying to use it, it is not a wildcard. The column name just contains an underscore.
The documenation on Database Object Names and Qualifiers shows the rules for object names, including rule 6:
Nonquoted identifiers must begin with an alphabetic character from your database character set. Quoted identifiers can begin with any character.
As your column name starts with an underscore, the column must have been defined with a quoted identifier when the table was created, e.g.:
create table your_table (test number, "_Test_" number);
You can see the exact name for each column in the data dictionary:
COLUMN_NAME
------------------------------
TEST
_Test_
If a column (or any object) follows the non-quoted-identifier rules then it is recorded in uppercase in the data dictionary, but you can refer to it without quotes and with any case; so any of these are valid:
select * from your_table where TEST = 123;
select * from your_table where Test = 123;
select * from your_table where test = 123;
select * from your_table where tEsT = 123;
But if for a quoted identifier you always have to uses quotes and exactly the same case when referring to it. So these error:
select * from your_table where _TEST_ = 123;
select * from your_table where _Test_ = 123;
select * from your_table where "_TEST_" = 123;
(the first two with ORA-00911: invalid character, the third with ORA-00904: "_TEST_": invalid identifier because of the case difference). You have to match exactly, so only this is valid:
select * from your_table where "_Test_" = 123;
This is why quoted identifiers are a pain to work with and should be avoided if possible. Oracle even advise against using them.

Related

Snowflake column with triple double-quotes is always flagged as "Invalid identifier"

Multiple snowflake columns are like this """SOME TEXT WITH SPACES"""
No issue when I'm doing a SELECT * FROM MY_TABLE
But I can't figure out how to query the columns with double-quotes...
If I do :
SELECT """SOME TEXT WITH SPACES""" FROM MY_TABLE
I receive
SQL compilation error: error line 1 at position 7 invalid identifier '""SOME TEXT WITH SPACES""'
I've tried adding other double-quotes but I can't find the right combination...
If you have a table when selected from:
select * from names;
looks likes this:
NO_QUOTE
also_no_quote
"single_quotes"
"""triple_quotes"""
0
0
1
3
You need to understand how it was created, which is also how it need to be accessed :
There is the first layer of double quotes to turn off the case insensitivity.
Then for each extra layer of wanted double quotes in the output you have to use two double quotes on both sides.
Thus tripple quotes was made and accessed by 7 double quotes:
create or replace table names (no_quote int,
"also_no_quote" int,
"""single_quotes""" int,
"""""""triple_quotes""""""" int);
insert into names values (0,0,1,3);
and thus can be accessed by:
select no_quote, "also_no_quote", """single_quotes""", """""""triple_quotes""""""" from names;
You need to select the column name using quotes because column names are case sensitive if they are created in double quotes.
Example
create or replace table doublequotes (
seq int,
"""last_name""" string,
first_name string
);
insert into doublequotes values (10, 'abcd', 'efgh');
select """last_name""" from doublequotes;
o/p: abcd
Please try.

How to SELECT COL_"NAME" in Snowflake ? (COLUMN name containing double quote)

I know this is very bad naming practice, but I am not the owner of the table...
I need to run :
SELECT COL_"NAME"
FROM TABLE
where COL_"NAME" is the name of the column, containing double quotes.
I tried :
SELECT COL_""NAME""
FROM TABLE
SELECT COL_\"NAME\"
FROM TABLE
But nothing works
Identifier Requirements:
To use the double quote character inside a quoted identifier, use two quotes.
To access column: COL_"NAME"
SELECT "COL_""NAME"""
FROM TABLE;

Oracle DB quote column names

When using regular tables, its fine to use the following Oracle SQL query:
SELECT max(some_primary_key) FROM MyTable
However, when using Database Objects (i.e. a table of an object), this yields to the following error:
ORA-00904: "SOME_PRIMARY_KEY": invalid identifier
When quoting the column name, like this:
SELECT max("some_primary_key") FROM MyTable
This works like expected. Why is it necessary to escape column names when working with Objects, but not with Tables?
It doesn't have to do with objects or tables, it has to do with how these objects/tables have been created.
If you do
create table "blabla" then you always need to address this table with "blabla", if you do create table blabla then you can address this table via BLABLA or blabla or bLabLa. Using " " makes the name case sensitive and that is the reason why most developers don't use " " because usually you don't want case sensitive names .
Database Object Naming Rules
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.
A nonquoted identifier is not surrounded by any punctuation.
You can use either quoted or nonquoted identifiers to name any
database object. However, database names, global database names, and
database link names are always case insensitive and are stored as
uppercase. If you specify such names as quoted identifiers, then the
quotation marks are silently ignored. Refer to CREATE USER for
additional rules for naming users and passwords.
To summarize this
When you do :
SELECT max(some_primary_key) FROM MyTable
Oracle assume that your column was declared like this :
CREATE TABLE MyTable (
some_primary_key INT,
...
)
Seing the resulting error, it's not the case. You obviously declared it like this :
CREATE TABLE MyTable (
"some_primary_key" INT,
...
)
And you should thus always refer to that column using double quotes and proper case, thus :
SELECT max("some_primary_key") FROM MyTable
The bible : Oracle Database Object Names and Qualifiers
[TL;DR] The simplest thing to do is to never use double quotes around object names and just let oracle manage the case-sensitivity in its default manner.
Oracle databases are, by default, case sensitive; however, they will also, by default, convert everything to upper-case so that the case sensitivity is abstracted from you, the user.
CREATE TABLE Test ( column_name NUMBER );
Then:
SELECT COUNT(column_name) FROM test;
SELECT COUNT(Column_Name) FROM Test;
SELECT COUNT(COLUMN_NAME) FROM TEST;
SELECT COUNT(CoLuMn_NaMe) FROM tEsT;
SELECT COUNT("COLUMN_NAME") FROM "TEST";
Will all give the same output and:
DESCRIBE test;
Outputs:
Name Null Type
----------- ---- ------
COLUMN_NAME NUMBER
(Note: Oracle's default behaviour is to convert the name to upper case.)
If you use double quotes then oracle will respect your use of case in the object's name (and you are then required to always use the same case):
CREATE TABLE "tEsT" ( "CoLuMn_NaMe" NUMBER );
(Note: Both the table and column name are surrounded in double quotes and now require you to use exactly the same case, and quotes, when you refer to them.)
Then you can only do (since you need to respect the case sensitivity):
SELECT COUNT("CoLuMn_NaMe") FROM "tEsT";
And
DESCRIBE "tEsT";
Outputs:
Name Null Type
----------- ---- ------
CoLuMn_NaMe NUMBER
(Note: Oracle has respected the case sensitivity.)
I created one object in Oracle 11g:
CREATE OR REPLACE TYPE MyType AS OBJECT (
some_property NUMBER(20),
CONSTRUCTOR FUNCTION MyType(some_property number default 123) RETURN SELF AS RESULT
) NOT FINAL;
/
CREATE OR REPLACE TYPE BODY MyType AS
CONSTRUCTOR FUNCTION MyType(some_property number default 123)
RETURN SELF AS RESULT
AS
BEGIN
SELF.some_property := some_property;
RETURN;
END;
END;
/
---Created a table of my object
CREATE TABLE MYTABLE OF MYTYPE ;
---issued the statement.
SELECT max(some_property) FROM MYTABLE;
Its working fine for me without quotes. Not sure why its not working in your case. Whats your oracle version ?

What's wrong with my sql in oracle?

What's wrong with my sql in oracle? There are some data in my table,I select all of them and I can get them.but I can not search them if I add a condition.When did I add single or double quotation marks in my sql?Now I find that when I write some search statement,I must add single quotation marks.And when I write some insert statement,I must add double quotation marks.Or my sql will run bad.How to judge when should I use the different quotation in my sql?
select * from T_STUDENT
and the result is:
sex(varchar2) phone(varchar2) birthtime(timestamp)
1 13553812147 2016-06-03 16:02:00.799 **
When I add a search condition,but the result is null.
//error:ORA-000904
select * from T_STUDENT where phone='13553812147'
//error:ORA-000904
select * from T_STUDENT where PHONE='13553812147'
//run well but result is null
select * from T_STUDENT where 'phone'='13553812147'
And the same question I meet in the insert statement.
//error:ORA-000904
insert into T_STUDENT (sex,phone,birthtime) values('1','12345645454','2016-06-04 16:02:00.799')
//error:ORA-000928 missing select keyword
insert into T_STUDENT ('sex','phone','birthtime') values('1','12345645454','2016-06-04 16:02:00.799')
//run well but must add double quotation marks
insert into T_STUDENT ("sex","phone","birthtime") values('1','12345645454','2016-06-04 16:02:00.799')
This is because your table was defined using double quotes around the column names:
create table t_student
( "sex" varchar2(1)
, "phone" varchar2(30)
, "birthtime" timestamp
);
Using double quotes makes the names case-sensitive and so for ever after they must be referenced in double quotes, since by default Oracle is nicely case-insensitive. For this reason you should never use double quotes when creating tables, views etc.
I've had the chance to look at this and Tony Andrews' answer is correct, you actually get invalid identifier as error message when you type an invalid column, which includes a case mismatch, though the error message will mention the exact identifier:
SQL> select * from T_STUDENT where phone='13553812147';
select * from T_STUDENT where phone='13553812147'
*
ERROR at line 1:
ORA-00904: "PHONE": invalid identifier
SQL> select * from T_STUDENT where funny_bunny='13553812147';
select * from T_STUDENT where funny_bunny='13553812147'
*
ERROR at line 1:
ORA-00904: "FUNNY_BUNNY": invalid identifier
The only thing missing from his answer is that Oracle will always make an internal cast to uppercase for any unquoted identifier, as the full error message illustrates. That's why phone='13553812147' won't match a column defined as "phone" (but "phone"='13553812147' will do).
Last but not least, single quotes define plain strings rather than object names so when you do this:
select * from T_STUDENT where 'phone'='13553812147'
... you aren't filtering by phone column at all. Instead, you have a constant condition that's always false (text "phone" equals text "13553812147").

PostgreSQL column 'foo' does not exist

I have a table that has 20 integer columns and 1 text column named 'foo'
If I run query:
SELECT * from table_name where foo is NULL
I get error:
ERROR: column "foo" does not exist
I have checked myself that his column indeed exists. If I do something like:
SELECT * from table_name where count is NULL
The resulting output shows 'foo' as one of the columns....
I am guessing I have to do something special in the query because foo is a text column...
Thanks for the help (POSTGRESQL 8.3)
You accidentally created the column name with a trailing space and presumably phpPGadmin created the column name with double quotes around it:
create table your_table (
"foo " -- ...
)
That would give you a column that looked like it was called foo everywhere but you'd have to double quote it and include the space whenever you use it:
select ... from your_table where "foo " is not null
The best practice is to use lower case unquoted column names with PostgreSQL. There should be a setting in phpPGadmin somewhere that will tell it to not quote identifiers (such as table and column names) but alas, I don't use phpPGadmin so I don't where that setting is (or even if it exists).
If for some reason you have created a mixed-case or upper-case column name, you need to quote it, or get this error:
test=> create table moo("FOO" int);
CREATE TABLE
test=> select * from moo;
FOO
-----
(0 rows)
test=> select "foo" from moo;
ERROR: column "foo" does not exist
LINE 1: select "foo" from moo;
^
test=> _
Note how the error message gives the case in quotes.
PostreSQL apparently converts column names to lower case in a sql query - I've seen issues where mixed case column names will give that error. You can fix it by putting the column name in quotation marks:
SELECT * FROM table_name where "Foo" IS NULL
I fixed it by changing the quotation mark (") with apostrophe (') inside Values. For instance:
insert into trucks ("id","datetime") VALUES (862,"10-09-2002 09:15:59");
Becomes this:
insert into trucks ("id","datetime") VALUES (862,'10-09-2002 09:15:59');
Assuming datetime column is VarChar.
As others suggested in comments, this is probably a matter of upper-case versus lower-case, or some whitespace in the column name. (I'm using an answer so I can format some code samples.) To see what the column names really are, try running this query:
SELECT '"' || attname || '"', char_length(attname)
FROM pg_attribute
WHERE attrelid = 'table_name'::regclass AND attnum > 0
ORDER BY attnum;
You should probably also check your PostgreSQL server log if you can, to see what it reports for the statement.
If you quote an identifier, everything in quotes is part of the identifier, including upper-case characters, line endings, spaces, and special characters. The only exception is that two adjacent quote characters are taken as an escape sequence for one quote character. When an identifier is not in quotes, all letters are folded to lower-case. Here's an example of normal behavior:
test=# create table t (alpha text, Bravo text, "Charlie" text, "delta " text);
CREATE TABLE
test=# select * from t where Alpha is null;
alpha | bravo | Charlie | delta
-------+-------+---------+--------
(0 rows)
test=# select * from t where bravo is null;
alpha | bravo | Charlie | delta
-------+-------+---------+--------
(0 rows)
test=# select * from t where Charlie is null;
ERROR: column "charlie" does not exist
LINE 1: select * from t where Charlie is null;
^
test=# select * from t where delta is null;
ERROR: column "delta" does not exist
LINE 1: select * from t where delta is null;
^
The query I showed at the top yields this:
?column? | char_length
-----------+-------------
"alpha" | 5
"bravo" | 5
"Charlie" | 7
"delta " | 6
(4 rows)
In my case when i run select query it works and gives desired data. But when i run query like
select * from users where email = "user#gmail.com"
It shows this error
ERROR: column "user#gmail.com" does not exist
LINE 2: select * from users where email = "user#gmail.com...
^
SQL state: 42703
Character: 106
Then i use single quotes instead of double quotes for match condition, it works. for ex.
select * from users where email = 'user#gmail.com'
It could be quotes themselves that are the entire problem. I had a similar problem and it was due to quotes around the column name in the CREATE TABLE statement. Note there were no whitespace issues, just quotes causing problems.
The column looked like it was called anID but was really called "anID". The quotes don't appear in typical queries so it was hard to detect (for this postgres rookie). This is on postgres 9.4.1
Some more detail:
Doing postgres=# SELECT * FROM test; gave:
anID | value
------+-------
1 | hello
2 | baz
3 | foo (3 rows)
but trying to select just the first column SELECT anID FROM test; resulted in an error:
ERROR: column "anid" does not exist
LINE 1: SELECT anID FROM test;
^
Just looking at the column names didn't help:
postgres=# \d test;
Table "public.test"
Column | Type | Modifiers
--------+-------------------+-----------
anID | integer | not null
value | character varying |
Indexes:
"PK on ID" PRIMARY KEY, btree ("anID")
but in pgAdmin if you click on the column name and look in the SQL pane it populated with:
ALTER TABLE test ADD COLUMN "anID" integer;
ALTER TABLE test ALTER COLUMN "anID" SET NOT NULL;
and lo and behold there are the quoutes around the column name. So then ultimately postgres=# select "anID" FROM test; works fine:
anID
------
1
2
3
(3 rows)
Same moral, don't use quotes.
the problem occurs because of the name of column is in camel case
internally it wraps it in " "(double quotes)
to solve this, at the time of inserting values in table use single quotes ('')
e.g.
insert into schema_name.table_name values(' ',' ',' ');
We ran into this issue when we created the table using phppgadmin client. With phppgadmin we did not specify any double quotes in column name and still we ran into same issue.
It we create column with caMel case then phpPGAdmin implicitly adds double quotes around the column name. If you create column with all lower case then you will not run into this issue.
You can alter the column in phppgadmin and change the column name to all lower case this issue will go away.
I fixed similar issues by qutating column name
SELECT * from table_name where "foo" is NULL;
In my case it was just
SELECT id, "foo" from table_name;
without quotes i'v got same error.
I also ran into this error when I was using Dapper and forgot to input a parameterized value.
To fix I had to ensure that the object passed in as a parameter had properties matching the parameterised values in the SQL string.
I am working with address data and used pandas to load the data to Postgres. The pandas_usaddress library did a great job parsing my address, but put the new columns InSpeCific case. crazy. But now I have to use double quotes with each column name. select "ZipCode" from har_addresses; And I get my data.