Is there a difference between the following two queries?
CREATE TABLE alpha(age INTEGER);
and
CREATE TABLE alpha("age" INTEGER);
I read that database objects are case INSENSITIVE unless they are kept in quotation marks.
This applies when I try to keep the TABLE object in quotation marks but isn't working for the attributes.
I guess the reason is attributes are not database objects. Is this correct?
If yes, then in what category does attributes fall under, if not database object?
Is there a difference ? yes.
when you don't use quotes, like:
CREATE TABLE alpha(age INTEGER);
oracle will store that column and table as UPPERCASE in the data dictionary.
in other words , these statements are identical:
CREATE TABLE alpha(age INTEGER);
CREATE TABLE "ALPHA"("AGE" INTEGER);
CREATE TABLE ALPHA(AGE INTEGER);
Also, any subsequent dml/ddl on the table like:
select age from alpha;
would be first converted to uppercase when looking up the object/column; so the above SQL would work fine. i.e oracle would look for the column AGE and the table ALPHA and not the column age or the table alpha as was typed.
however, when you create with a quoted identifier:
CREATE TABLE alpha("age" INTEGER);
oracle would create table ALPHA with a column in lowercase age (check user_tab_columns to see this). so ONLY the following would work to select it:
select "age" from alpha;
select "age" from "ALPHA";
select "age" from ALPHA;
and not:
select age from alpha;
eg:
http://sqlfiddle.com/#!4/3084e/1
It depends on the database engine, and even how the database itself or the connected session is configured. However, in general, SQL Server would treat age and "age" as the same identifier, while Oracle would consider age and "age" to be different.
In regard to attributes (columns), treatment of those identifiers vary widely as well. Most database engines will allow the attributes to be identified by quotation marks (or other delimiters) and in the same way the table identifiers are handled.
Related
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 ?
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))";
Is there any term like 'DOT(.) notation' used in SQL joins?
if practised, pls explain how to use it.
Thanks in advance.
Yes here is how you do it
When you do your SELECT
SELECT firstname, lastname from dbo.names n -- The n becomes an alias
JOIN address a --- another alias
on a.userid = n.userid
Collated from multiple sources of official documentation.
Dot notation (sometimes called the membership operator) allows you to qualify an SQL identifier with another SQL identifier of which it is a component. You separate the identifiers with the period ( . ) symbol. For example, you can qualify a column name with any of the following SQL identifiers:
Table name: table_name.column_name
View name: view_name.column_name
Synonym name: syn_name.column_name
These forms of dot notation are called column projections.
You can also use dot notation to directly access the fields of a named or unnamed ROW column, as in the following example:
row-column name.field name
This use of dot notation is called a field projection. For example, suppose you have a column called rect with the following definition:
CREATE TABLE rectangles
(
area float,
rect ROW(x int, y int, length float, width float)
)
The following SELECT statement uses dot notation to access field length of the rect column:
SELECT rect.length FROM rectangles WHERE area = 64
Selecting Nested Fields
When the ROW type that defines a column itself contains other ROW types, the column contains nested fields. Use dot notation to access these nested fields within a column.
For example, assume that the address column of the employee table contains the fields: street, city, state, and zip. In addition, the zip field contains the nested fields: z_code and z_suffix. A query on the zip field returns values for the z_code and z_suffix fields. You can specify, however, that a query returns only specific nested fields. The following example shows how to use dot notation to construct a SELECT statement that returns rows for the z_code field of the address column only:
SELECT address.zip.z_code
FROM employee
Rules of Precedence
The database server uses the following precedence rules to interpret dot notation:
schema name_a . table name_b . column name_c . field name_d
table name_a . column name_b . field name_c . field name_d
column name_a . field name_b . field name_c . field name_d
When the meaning of an identifier is ambiguous, the database server uses precedence rules to determine which database object the identifier specifies. Consider the following two tables:
CREATE TABLE b (c ROW(d INTEGER, e CHAR(2));
CREATE TABLE c (d INTEGER);
In the following SELECT statement, the expression c.d references column d of table c (rather than field d of column c in table b) because a table identifier has a higher precedence than a column identifier:
SELECT *
FROM b,c
WHERE c.d = 10
For more information about precedence rules and how to use dot notation with ROW columns, see the IBM Informix: Guide to SQL Tutorial.
Using Dot Notation with Row-Type Expressions
Besides specifying a column of a ROW data type, you can also use dot notation with any expression that evaluates to a ROW type. In an INSERT statement, for example, you can use dot notation in a subquery that returns a single row of values. Assume that you created a ROW type named row_t:
CREATE ROW TYPE row_t (part_id INT, amt INT)
Also assume that you created a typed table named tab1 that is based on the row_t ROW type:
CREATE TABLE tab1 OF TYPE row_t
Assume also that you inserted the following values into table tab1:
INSERT INTO tab1 VALUES (ROW(1,7));
INSERT INTO tab1 VALUES (ROW(2,10));
Finally, assume that you created another table named tab2:
CREATE TABLE tab2 (colx INT)
Now you can use dot notation to insert the value from only the part_id column of table tab1 into the tab2 table:
INSERT INTO tab2
VALUES ((SELECT t FROM tab1 t
WHERE part_id = 1).part_id)
The asterisk form of dot notation is not necessary when you want to select all fields of a ROW-type column because you can specify the column name alone to select all of its fields. The asterisk form of dot notation can be quite helpful, however, when you use a subquery, as in the preceding example, or when you call a user-defined function to return ROW-type values.
Suppose that a user-defined function named new_row returns ROW-type values, and you want to call this function to insert the ROW-type values into a table. Asterisk notation makes it easy to specify that all the ROW-type values that the new_row( ) function returns are to be inserted into the table:
INSERT INTO mytab2 SELECT new_row (mycol).* FROM mytab1
References to the fields of a ROW-type column or a ROW-type expression are not allowed in fragment expressions. A fragment expression is an expression that defines a table fragment or an index fragment in SQL statements like CREATE TABLE, CREATE INDEX, and ALTER FRAGMENT.
Additional Examples of How to Specify Names With the Dot Notation
Dot notation is used for identifying record fields, object attributes, and items inside packages or other schemas. When you combine these items, you might need to use expressions with multiple levels of dots, where it is not always clear what each dot refers to. Here are some of the combinations:
Field or Attribute of a Function Return Value
func_name().field_name
func_name().attribute_name
Schema Object Owned by Another Schema
schema_name.table_name
schema_name.procedure_name()
schema_name.type_name.member_name()
Packaged Object Owned by Another User
schema_name.package_name.procedure_name()
schema_name.package_name.record_name.field_name
Record Containing an Object Type
record_name.field_name.attribute_name
record_name.field_name.member_name()
Differences in Name Resolution Between PL/SQL and SQL
The name resolution rules for PL/SQL and SQL are similar. You can avoid the few differences if you follow the capture avoidance rules. For compatibility, the SQL rules are more permissive than the PL/SQL rules. SQL rules, which are mostly context sensitive, recognize as legal more situations and DML statements than the PL/SQL rules.
PL/SQL uses the same name-resolution rules as SQL when the PL/SQL compiler processes a SQL statement, such as a DML statement. For example, for a name such as HR.JOBS, SQL matches objects in the HR schema first, then packages, types, tables, and views in the current schema.
PL/SQL uses a different order to resolve names in PL/SQL statements such as assignments and procedure calls. In the case of a name HR.JOBS, PL/SQL searches first for packages, types, tables, and views named HR in the current schema, then for objects in the HR schema.
Is it possible to create a table with column name containing space? If so how can I create and use it?
It is possible, but it is not advisable. You need to enclose the column name in double quotes.
create table my_table ("MY COLUMN" number);
But note the warning in the documentation:
Note: 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.
The name will be case-sensitive, and you wil have to enclose the name in double quotes every time you reference it:
select "MY COLUMN" from my_table;
So... don't, would be my advice...
Yes, it's possible. You just have to be sure to quote the column name. For instance:
CREATE TABLE Fubar ("Foo Bar" INT);
INSERT INTO Fubar VALUES (1337);
SELECT "Foo Bar" FROM SpaceMonster
Even though it's possible, it doesn't make it a good idea. You'll probably save yourself from a lot of pain if just replace all you spaces with underscores.
it is possible by naming the column between two "
example: "My columN" , the column name becomes case sensitive which means.
SELECT "my column" from table; --NOT OK
SELECT "My columN" from table; --OK
You can (see the Oracle doc) if you quote these appropriately. However I suspect this is not a good idea, since you'll have to quote everything. Generally db naming standards / conventions (e.g. here or here) favour using underscores (which don't require quoting) over whitespace.
This is the columns rule defined for oracle
Columns (for tables)
All columns are in form {alias}_{colname}. For example prs_id,
prs_name, prs_adr_id, adr_street_name. This guarantees that column
names are unique in a schema, except denormalized columns from
another table, which are populated using triggers or application
logic.
All columns are in singular. If you think you need a column name in plural think twice whether it is the right design? Usually it
means you are including multiple values in the same column and that
should be avoided.
All tables have surrogate primary key column in form {alias}_id, which is the first column in the table. For example, prs_id, mat_id,
adr_id.
you can always have alias for column name bu using ""
Did you Google for this? I did - the 6th link was this, in which I find the following:
create table employee (
"First Name" varchar2(20),
"Last Name" varchar2(20),
Address varchar2(60),
Phone varchar2(15),
Salary number,
EmpID number,
DeptID number
);
... which works fine when I tried it in 10g.
This question is based on this answer.
What does the following sentence mean?
Finally, don't use mixed case
identifiers. Do everything lowercase,
so you don't have to quote them.
Does it mean that I should change the commands such as CREATE TABLE, USER_ID and NOT NULL to lowercase? - It cannot because it would be against common naming conventions.
In PostgreSQL, an unquoted identifier is converted into lowercase:
CREATE TABLE "MYTABLE" (id INT NOT NULL);
CREATE TABLE "mytable" (id INT NOT NULL);
INSERT
INTO "MYTABLE"
VALUES (1);
INSERT
INTO "mytable"
VALUES (2);
SELECT *
FROM mytable;
---
2
SELECT *
FROM MYTABLE;
---
2
Both queries will return 2, since they are issued against "mytable", not "MYTABLE".
To return 1 (i. e. issue a query against "MYTABLE", not "mytable"), you need to quote it:
SELECT *
FROM "MYTABLE";
---
1
CREATE TABLE etc. are not identifiers, they are reserved words.
You can use them in any case you like.
No, I think the gentleman referred to using all lowercase identifiers, e.g. table, column etc. names. This should have no impact on the commands like CREATE TABLE etc. that you use.
Marc
I have no idea why he said that. In SQL Server, at least, the case of an identifier doesn't matter. Maybe it does in other DBMS systems?