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

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.

Related

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.

Where is this Oracle object?

I have some SQL scripts; one of them references an object called "names". I can:
select * from names
and it returns results. However, I cannot see a table called "names". Neither can I see a view called "names". I can't find a custom type called "names".
If I look for one of the columns that is returned by the query select * from names using:
select * from sys.all_tab_columns where column_name like '%MyColumn%'
it finds a table called LSNAMES, but that has no rows.
Any ideas how I can find this "table"?
I'd start the research with understanding what type of object this is:
SELECT owner, object_name, object_type
FROM all_objects
WHERE object_name = 'NAMES'
Once you have a type, you could query some more information from all_<type>s
Look for:
A materialized view called NAMES
SELECT * FROM ALL_MVIEWS WHERE MVIEW_NAME = 'NAMES';
A synonym called NAMES
SELECT * FROM ALL_SYNONYMS WHERE SYNONYM_NAME = 'NAMES';

SELECT a table from oracle data dictionary

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.

How to correctly make a public synonym

This is a pretty silly one, but I need help.
I have a table owned by mydbowner. It is named mydbowner.mytable. I tried to make a public synonym by issuing the command:
CREATE OR REPLACE PUBLIC SYNONYM mytable FOR mydbowner.mytable;
When I do this, and I query the table I get:
ORA-01775: looping chain of synonyms
How do I make this synonym without having the problem.
I think Justin is on the right track. What I think it actually means is that mydbowner.mytable doesn't exist.
Here's an example:
SQL> conn mbobak
Enter password:
Connected.
SQL> drop table mytable;
drop table mytable
*
ERROR at line 1:
ORA-00942: table or view does not exist
SQL> create public synonym mytable for mbobak.mytable;
Synonym created.
SQL> select * from mytable;
select * from mytable
*
ERROR at line 1:
ORA-01775: looping chain of synonyms
I think what's happening is that Oracle tries to resolve mytable, there is no mytable in mbobak schema, so it looks for it in PUBLIC, it finds it, and sees that it points to mbobak.mytable. But, mbobak.mytable doesn't exist, so, it looks for mytable in PUBLIC, and there's the loop.
And in fact, if you create mytable, the error goes away:
SQL> create table mytable as select * from dual;
Table created.
SQL> select * from mytable;
D
-
X
1 row selected.
SQL> drop table mytable;
Table dropped.
SQL> select * from mytable;
select * from mytable
*
ERROR at line 1:
ORA-01775: looping chain of synonyms
Yes, I realize that doesn't really entirely make sense, as, once the public synonym resolved to mbobak.mytable, and that's not found, it seems to me, it should return an error ORA-942 "table or view does not exist", which makes far more sense to me.
But, this does seem to be how it works.
QED
Hope that helps.
The error you're getting implies that mydbowner.mytable is not, in fact a table. What does
SELECT object_type
FROM all_objects
WHERE owner = 'MYDBOWNER'
AND object_name = 'MYTABLE'
return?

Resources