SELECT a table from oracle data dictionary - oracle

I am new to SQL and recently installed Oracle 11g. I read the post here on selecting all tables from user_tables. I'm trying to select a specific table and following some of the suggestions in the post does not appear to work.
The following executes fine and returns all tables available to me including a table named faculty_t:
select * from user_tables;
select * from dba_tables;
select * from all_tables;
desc faculty_t;
But I get error when I do the following:
select * from user_tables where table_name = FACULTY_T;
The first set of statements confirm that I do have a table named faculty_t. However, trying to select this table from user_tables, all_tables, or dba_tables does not appear to work for me right now. The error message reads something like:
ORA-00904: "FACULTY_T": invalid identifier
00904. 00000 - "%s: invalid identifier"
*Cause:
*Action:
Error at Line: 208 Column: 8
Any thoughts? Thanks!

String literals in SQL are wrapped in '. So:
select * from user_tables where table_name = 'FACULTY_T';
When you did a desc faculty_t, the SQL engine knew that a table name was expected at that spot (the syntax expects a table name there). But in your select query, sql is just looking for the value of a column that happens to have a string data type, so you need to use the ' for a string literal.

Related

Oracle - ORA-00907: missing right parenthesis in query generated by Odata query generator

this is the query generated by an Odata Sql query generator and I am on Oracle 12c
SELECT ID
FROM MY_TABLE
WHERE (
NAME LIKE 'abc' = true
)
;
and the error it generates is
ORA-00907: missing right parenthesis
00907. 00000 - "missing right parenthesis"
*Cause:
*Action:
Error at Line: 4 Column: 14
Any ideas on how to fix the query ?
Thanks in advance
I know nothing about "Odata Sql query generator", but - if you want to fix this query, then it would be
select id from my_table where name like 'abc'
On the other hand, that's same as
select id from my_table where name = 'abc'
so perhaps you actually meant to use wildcards:
select id from my_table where name like '%abc%'

Oracle puzzle: Selecting from a non-existing table

I have a table named "libisatz" in my database, and there is no table, nor view with name "libiSatz" (with capital S instead of s) and I don't find any kind of object in my schema having name "libiSatz". But, surprisingly selecting from "libiSatz" results in the same result as if I had written "libisatz". If I change any other letter in this name from lower case to upper case (e.g. I write "Libisatz", then I get an error. How can this be?.
ADDENDUM
I've checked the ideas of #Jon Heller with the following result:
Both select * from DBA_OBJECTS where OBJECT_NAME like 'libi_atz'; and select * from DBA_OBJECTS where lower(OBJECT_NAME) = 'libisatz'; returns one single row (it is the "libisatz" table)
select * from DBA_OBJECTS where OBJECT_NAME = 'libisatz'; returns one row and select * from DBA_OBJECTS where OBJECT_NAME = 'libiSatz'; returns no row.
Both select * from DBA_SQL_TRANSLATIONS; and select * from DBMS_ADVANCED_REWRITE; results in ORA-00942: table or view does not exist
select * from DBA_REWRITE_EQUIVALENCES; results in no rows selected
select DUMP(OBJECT_NAME) from DBA_OBJECTS where lower(OBJECT_NAME) = 'libisatz'; returns Typ=1 Len=8: 108,105,98,105,115,97,116,122
So it seems that the puzzle is not yet solved.
ADDENDUM 2.
When I try to create a view named "libiSatz" then I get
ORA-00955: name is already used by an existing object
in spite of the results above.
After I renamed "libiSatz" to "oraclepuzzle",
select count(*) from "libisatz"; and "select count(*) from "oraclepuzzle"; works, but select count(*) from "libiSatz"; doesn't.
select * from dba_objects where object_name in ( 'oraclepuzzle', 'libisatz', 'libiSatz'); returns one row with object_name "oraclepuzzle".
Do you have SQL translations, rewrite equivalances, or UTF8 characters?
The SQL translation framework was built to allow applications designed for other database types to seamlessly query Oracle. But instead of translating syntaxes, the feature could also be used to silently change your queries. For example, here is an example of querying a table that does not exist in order to workaround table size limitations. Check the view DBA_SQL_TRANSLATIONS.
Rewrite equivalences can be created by the package DBMS_ADVANCED_REWRITE, and can be used to silently change the results of wrong queries or for some rare performance problems. (In my simple tests I wasn't able to get this query to work for invalid queries, but I bet there is a way to make it work.) Check the view DBA_REWRITE_EQUIVALENCES.
UTF8 characters may be silently swapped out for similar ASCII characters. This probably depends on your database and client character set settings. The below example is pretty obviously not an ASCII "S", but you may have a more subtle problem. Check the source of your values, retype them manually, and use the DUMP function to evaluate the binary of the characters.
SQL> create table "libisatz"(a number);
Table created.
SQL> -- An uppercase "S" does not work
SQL> select * from "libiSatz";
select * from "libiSatz"
*
ERROR at line 1:
ORA-00942: table or view does not exist
SQL> -- But a "LATIN SMALL LETTER S WITH CARON" works.
SQL> select * from "libiĆĄatz";
no rows selected
Lastly, are you 100% sure that the object doesn't exist on your database? The above examples are possible, but extremely rare. Triple-check DBA_OBJECTS.OBJECT_NAME for the mystery object.
My deafult Oracle object names are case insensitive.
So, when you issue teh command:
CREATE TABLE the_table ..
CREATE TABLE The_Table ..
CREATE TABLE THE_TABLE ..
The underlying object name in all cases is THE_TABLE, but you can access it using any mix of upper/lower case:
SELECT * FROM THE_TABLE
SELECT * FROM tHe_TaBlE
SELECT * FROM the_table
Will all work.
When a table is created with the name wrapped in double-quotes, the name becomes case-sensitive.
So, if you issue:
CREATE TABLE "libiSatz" ..
Then the table name in all SQL statements must match the exact name in the double quotes, i.e.
SELECT * FROM "libiSatz" is OK (Correction following comments)
SELECT * FROM libisatz is NOT OK
SELECT * FROM LibiSatz is NOT OK
When you search for this in USER_OBJECTS or USER_TABLES you will have to match the creation name:
SELECT * FROM USER_OBJECTS WHERE OBJECT_NAME = 'libiSatz';

EFCore error:- ORA-00904: "m"."Id": invalid identifier

I am working with an application using asp.net core 2.2 and efcore database first approach with Oracle database. I am using Oracle.EntityFrameworkCore (2.19.60) nuget package, successfully mapped db model, but when I try to fetch data from DBContext , getting error
ORA-00904: "m"."Id": invalid identifier
Oracle Database version: Oracle Database 12c Standard Edition Release 12.2.0.1.0 - 64bit Production
code:
var fetched = await myDatabaseContext.MyTableVersions.ToListAsync();
LinQ is generating following query :
SELECT "m"."Id", "m"."MAJORVERSION" FROM "MyTableVersions" "m"
Since It's not a correct syntax for PL/Sql query so getting error ORA-00904: "m"."Id": invalid identifier.
Is there any way to fix this error? Thanks.
I have searched on the web and found
Bug 30352492 - EFCORE: ORA-00904: INVALID IDENTIFIER
but that issue is related to schema.
The query is perfectly valid (db<>fiddle here), assuming your table looks something like
CREATE TABLE "MyTableVersions"
("Id" NUMBER,
MAJORVERSION NUMBER)
However, I suspect your table looks like
CREATE TABLE "MyTableVersions"
(ID NUMBER,
MAJORVERSION NUMBER)
I don't know what the class looks like that you're trying to fetch into, but I suspect it has a field named Id. If you can change the name of that field to ID (in other words, so that its capitalization matches the capitalization of the related database column) you might find it works then.
Double quotes are something you should avoid in Oracle world.
Your query:
SELECT "m"."Id", "m"."MAJORVERSION" FROM "MyTableVersions" "m"
means that column name is exactly Id (capital I followed by d). Only if that's really so, you should use double quotes. Otherwise, simply remove them:
SELECT m.id, m.MAJORVERSION FROM MyTableVersions m
The same goes for the table name - if it was created using mixed case (and you can't do that without double quotes), you'll have to use double quotes and exactly same letter case always. Otherwise, don't use them.
Oracle is case-insensitive regarding object and column names and are UPPERCASE by default:
SQL> create table test (id number);
Table created.
SQL> desc test
Name Null? Type
----------------------------------------- -------- -----------------
ID NUMBER
SQL> select table_name, column_name
2 from user_tab_columns
3 where table_name = 'TEST';
TABLE_NAME COLUMN_NAME
------------------------------ ------------------------------
TEST ID
SQL> insert into test (id) values (1);
1 row created.
SQL>
But, if you use mixed case with double quotes, then use them always:
SQL> create table "teST" ("Id" number);
Table created.
SQL> insert into test (id) values (1);
insert into test (id) values (1)
*
ERROR at line 1:
ORA-00942: table or view does not exist
SQL> insert into "test" (id) values (1);
insert into "test" (id) values (1)
*
ERROR at line 1:
ORA-00942: table or view does not exist
SQL> insert into "teST" (id) values (1);
insert into "teST" (id) values (1)
*
ERROR at line 1:
ORA-00904: "ID": invalid identifier
SQL> insert into "teST" ("Id") values (1);
1 row created.
SQL>
So: first make sure what table and column names really are, then use them appropriately.
To avoid problems with case-sensitivity, add the option to eliminate EF to add quotes to the generated queries. For instance, if you are using Devart Oracle provider, this is done in the following way:
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<AbpDbContextOptions>(options =>
{
var config = Devart.Data.Oracle.Entity.Configuration.OracleEntityProviderConfig.Instance;
config.Workarounds.DisableQuoting = true;
...
}
}
If you are using official provider - just inherit from DbCommandInterceptor (do quotes replacement with empty character in dbCommand in ...Executing methods), add this interceptor to DbContextOptionsBuilder instance.

How to select * from table () referencing a function from dblink

I'm just starting with PL/SQL. I have a function (table valued), and I can select it running:
SELECT *
FROM TABLE(fn_getsomething());
Ok, but I have to select a similar function (table valued as well) from a remote database #dbfs. How can I write this sentence?
I tried:
SELECT *
FROM TABLE (fn_get_rps_to_rm#dbfs())
//or
SELECT *
FROM TABLE (fn_get_rps_to_rm()#dbfs());
And it returns : 00904. 00000 - "%s: invalid identifier"
I had looked for similar questions, talking about table valued functions and dblink and I didn't find it.
I would recommend creating a view on the remote node say:
create or replace view fn_getsomething_view as
SELECT *
FROM TABLE(fn_getsomething());
then query from that view with the link, for example:
select * from fn_getsomething_view#dbfs;
hope this helps.

Ora-00905 missing keyword error

Im getting below error while executing below line,
SELECT * INTO employee_Backup FROM employee
Error:
Ora-00905 missing keyword error
Your query should be
INSERT INTO employee_backup
SELECT *
FROM employee
Discussed here
And the syntax is
INSERT INTO table_name
SELECT *
FROM table_name
This is sql-server syntax you're trying to use.
The Oracle equivalent would be:
INSERT INTO employee_backup
(SELECT * FROM employee)

Resources