In my Oracle DB setup all the tables are created under dedicated user account SYS0MYUSER. When executing following query on my system I got SQL Error: ORA-00903: invalid table name
SELECT COUNT(*) FROM SYS0MYUSER.USER;
I tried to escape the reserved keyword like this:
SELECT COUNT(*) FROM "SYS0MYUSER.USER";
But then I got another error SQL Error: ORA-00942: table or view does not exist
What is the correct way to escape user name + reserved keyword combination ?
UPDATE:
What's about table alias do I have to use double quotes too ?
If you have created the table using quoted identifier, then you must always use double-quotation marks wherever you refer the object.
From documentation,
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.
For example,
SQL> CREATE TABLE "USER"(A NUMBER);
Table created.
SQL>
SQL> SELECT COUNT(*) FROM LALIT.USER;
SELECT COUNT(*) FROM LALIT.USER
*
ERROR at line 1:
ORA-00903: invalid table name
SQL>
SQL> SELECT COUNT(*) FROM LALIT."USER";
COUNT(*)
----------
0
SQL>
So, you need to refer the table as a quoted identifier:
SELECT COUNT(*) FROM SYS0MYUSER."USER";
Update OP updated his question regarding table alias.
What's about table alias do I have to use double quotes too ?
Table alias has nothing to do with the quoted identifier.
For example,
SQL> SELECT t.* FROM LALIT."USER" t;
no rows selected
SQL>
SELECT COUNT(*) FROM "SYS0MYUSER"."USER";
Related
I'm using the sqldeveloper and have one database connection with the following connection string:
MES#//localhost:1521/xepdb1
MES is the schema owner and a select statement like this shows me what I want to see:
select count(*) from site
I'm also using Visual Studio and I'm trying to connect to the database by using the Oracle.ManagedDataAccess.Client
I'm using exactly the same connection string.
The connect to the database works fine. But I'm always getting the 00903 error.
Any idea what the problem can be ?
Many thanks in advance
I've tried also something like this:
select count(*) from mes.site
If you have used quoted identifiers to create the table then you will need to use quoted identifiers (and use the same case) whenever you access the table.
For example:
CREATE TABLE MES."site" (something NUMBER);
Then you would need to use:
SELECT count(*) FROM MES."site";
or
SELECT count(*) FROM mes."site";
or
SELECT count(*) FROM mEs."site";
The MES schema name is unquoted so you can use any case (and Oracle will implicitly convert it to upper-case to look it up in the data dictionary); however, "site" is a quoted identifier and Oracle will respect the case-sensitivity of the identifier and you MUST use the correct case and the surrounding quotes.
You can see the exact case you need to use in the result of the query:
SELECT owner, table_name FROM all_tables WHERE UPPER(table_name) = 'SITE';
If the data dictionary shows that the table name is upper-case then you can use an unquoted identifier (assuming that all the other naming rules have been respected and the table name is not a reserved/keyword) otherwise you will need to use a quoted identifier.
Normally you would get the ORA-00942: table or view does not exist exception but you can get ORA-00903: invalid table name when you use a keyword for a table name:
CREATE TABLE "NUMBER" (x) AS
SELECT 1 FROM DUAL;
Then:
SELECT COUNT(*) FROM NUMBER;
Give the exception:
ORA-00903: invalid table name
And:
SELECT COUNT(*) FROM "NUMBER";
Works.
However, MES and SITE are not keywords that should trigger that.
fiddle
Someone (not me) has created a number of restore points where the name includes a hyphen. For example restore_point-001.
When I try drop the restore point with Drop Restore Point it will error with sql command error saying that it is not properly ended. I have tried putting the name in single quotes and I have tried renaming the name, but v$restorepoint doesn't allow for this.
Is there a way to drop this restore point being named this way?
I have tried putting the name in single quotes ...
I'm not a DBA, but what you described reminds me of this:
Let's try to create a table whose name contains a "minus" sign (just like your restore point):
SQL> create table restore_point-001 (id number);
create table restore_point-001 (id number)
*
ERROR at line 1:
ORA-00922: missing or invalid option
Nope, it won't work. You said you enclosed the name into single quotes:
SQL> create table 'restore_point-001' (id number);
create table 'restore_point-001' (id number)
*
ERROR at line 1:
ORA-00903: invalid table name
SQL>
Nah, it's not a string literal.
So, let's try with double quotes:
SQL> create table "restore_point-001" (id number);
Table created.
Ha! It works! Let's now drop it: without any quotes:
SQL> drop table restore_point-001;
drop table restore_point-001
*
ERROR at line 1:
ORA-00933: SQL command not properly ended
Single quotes:
SQL> drop 'table restore_point-001';
drop 'table restore_point-001'
*
ERROR at line 1:
ORA-00950: invalid DROP option
Double quotes:
SQL> drop table "restore_point-001";
Table dropped.
SQL>
So, yes - I have no idea why people insist on "invalid" characters and what good does -001 do over _001, but - if I were you, I'd try with
drop restorepoint "restore_point-001";
and see what happens.
I'm having the following problem with an old database. We migrated from sql to oracle recently and I'm having trouble with an insert statement where the column name is "default". Any ideas (I'm not allowed to change the column name, that would be by far the best solution!)?
It looks somehow like this, only with a billion more columns and it's inside a large if-when-else construction for validating issues, so I can't drop the execute immediate.
EXECUTE IMMEDIATE 'INSERT INTO trytable (ID, "DEFAULT") VALUES (''monkey1'', 0)'
I don't think the problem comes from your column name, as shown in this working example:
SQL> CREATE TABLE trytable (ID VARCHAR2(10), "DEFAULT" NUMBER);
Table created
SQL> BEGIN
2 EXECUTE IMMEDIATE
3 'INSERT INTO trytable (ID, "DEFAULT") VALUES (''monkey1'', 0)';
4 END;
5 /
PL/SQL procedure successfully completed
Technically, you can have a table column name named DEFAULT, even if it's generally a bad idea that will lead to confusion. You will only be able to interact with it through the double-quote " syntax because DEFAULT is a reserved word.
If you specify double quotes around identifiers, Oracle will treat them as case-sensitive, so you have to make sure that they match the table specs.
In your case, it would help to have the specific error message.
The below will executes if your column name is "DEFAULT":
BEGIN
EXECUTE IMMEDIATE 'INSERT INTO TRYTABLE(ID, "DEFAULT")VALUES(''monkey1'',0)';
END;
"DEFAULT" and "default" makes difference.
I have a requirement where I have to select name of DB link (there are many DB links) from a table into bind variable and then fetch data from a table which is available in all DB links however data is different depending on DB link used. I am not getting a solution to use bind variables value as DB link.
This is my code:
select statement for fetching DB link into bind variable
SELECT DB_LINK into :v_db_link from reagions_db_links;
Then I have to use it for fetching data from table
SELECT reagion_id, region_name from Table_details#:v_db_link
I have tried to concatenate like below however its not working
SELECT reagion_id, region_name from Table_details#||:v_db_link
Please suggest me a solution, since I could have many DB links depending upon region selected by USER I am putting it into bind variable and then want to use it for fetching data from a table.
Substitution variables can be used for that. here is a quick example of how it can be done:
(Sql*plus environment).
-- set-up table that stores db_links
SQL> create table db_links(
2 dblink_name varchar2(31)
3 );
Table created.
--add a test dblink
SQL> insert into db_links(dblink_name) values ('TEST_DB_LINK');
1 row created.
SQL> commit;
Commit complete.
-- defining of a substitution variable dblink
SQL> column dblink_name new_value dblink noprint;
-- the value of the dblink_name column will be placed into the dblink
-- substitution variable declared previously
SQL> select dblink_name from db_links;
-- now we query a table using db link name stored
-- in the dblink substitution variable
-- prefacing it with ampersand.
SQL> select count(*) from dbusers#&dblink;
old 1: select count(*) from dbusers#&dblink
new 1: select count(*) from dbusers#TEST_DB_LINK
COUNT(*)
----------
351
SQL> spool off;
I use TOAD to do my PL/SQL development. In TOAD when i type a procedure name and press f4, I can see this procedure's source code. I think TOAD get the source code from v$sqltext view. To confirm my thought, I wrote a query:
select * from v$sqltext
but when I execute the upper query, Oracle give me an error:
ORA-00942: table or view does not
exist
00942. 00000 - "table or view does not exist"
*Cause:
*Action: Error at Line: 29 Column: 15
So I think TOAD get the procedure's source from other place instead of v$sqltext view. Anyone can tell me about this? Great thanks.
The full query for a stored procedure (not in a package):
select text
from all_source
where owner = 'MYSCHEMA'
and type = 'PROCEDURE'
and name = 'MY_PROCEDURE'
order by line;
If you are connected as user MYSCHEMA than you can use USER_SOURCE:
select text
from user_source
where type = 'PROCEDURE'
and name = 'MY_PROCEDURE'
order by line;
Other values for TYPE are:
TYPE BODY
FUNCTION
TRIGGER
TYPE
JAVA SOURCE
PACKAGE BODY
PACKAGE
select * from all_source
See Database Reference for ALL_SOURCE and V$SQLTEXT.
If you have select priv on DBA* tables, then do check out select * from dba_source. This table will have the entire source code.