Inner query not throwing error in postgres - oracle

There is a scenario in which we are retrieving some result from inner query and using the result to perform some operation
create table test1(key integer,value varchar)
insert into test1 values(1,'value 1');
insert into test1 values(2,'value 2');
insert into test1 values(3,'value 3');
second table as
create table test2(key1 integer, valuein varchar);
insert into test2 values (2,'value inside is 2');
insert into test2 values (4,'value inside is 4');
insert into test2 values (5,'value inside is 5');
the below query is giving result but in my view it should give an error
select * from test1 where key in
(select key from test2)
because key column does not exist in test2 table.
but it is giving result in postgres
but when run in oracle it is giving error as
ORA-00904: "KEY": invalid identifier
00904. 00000 - "%s: invalid identifier"

This is the correct behavior as specified in the SQL standard. The inner query has access to all columns of the outer query - and because test1 has a column named key (which, btw is a horrible name for a column) the inner select is valid.
See these discussions on the Postgres mailing list:
http://postgresql.nabble.com/BUG-13336-Unexpected-result-from-invalid-query-td5850684.html

Related

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.

The data model cannot be executed because of an error, please contact the administrator

I have a data sets that contains a columns which the parameters is by name, date and number. But everytime I view the data there's a error said The data model cannot be executed because of an error, please contact the administrator. But it only show the message but didn't show the details of the error. I also have a list of values because I set the parameter type of my parameters for name and number as a menu which is the result
that will return for the number is based on the name because if I didn't base it on the name it will return a 100+ values which is not okay to my user.
My query for my data set for example is,
select a.name, a.date, a.type_name, b.number, c.address
from details1 a, details2 b, details3 c
where
a.id = b.id
and b.id = c.id
and a.name = :name
and a.date between :start_date and :end_date
and b.number = :number
Query of List of Values for name
select a.name from details1 a
where a.type_name = 'person'
Query of List of Values for num
select b.number
from details1 a, details2 b
where 1=1
and a.id = b.id
and a.name = :name
I don't know BI Publisher, but - as far as Oracle is concerned, column name can not be number. It is reserved word for a datatype:
SQL> create table test (number number);
create table test (number number)
*
ERROR at line 1:
ORA-00904: : invalid identifier
Your query uses such a column:
select b.number ...
which can't work, unless someone created such a table by enclosing column name into double quotes, e.g.
SQL> create table test ("number" number);
Table created.
SQL> desc test
Name Null? Type
----------------------------------------- -------- ---------------
number NUMBER
SQL>
However, you'll have to specify such a column name using double quotes every time, paying attention to letter case (meaning: if column was created as "NumBER", you have to reference it exactly that way. "numBER" or "NUMber" or "nUmBeR" or "number" or "NUMBER" won't work). A few examples:
SQL> insert into test (number) values (1);
insert into test (number) values (1)
*
ERROR at line 1:
ORA-00928: missing SELECT keyword
SQL> insert into test ("NUMber") values (1);
insert into test ("NUMber") values (1)
*
ERROR at line 1:
ORA-00904: "NUMber": invalid identifier
SQL> insert into test ("NUMBER") values (1);
insert into test ("NUMBER") values (1)
*
ERROR at line 1:
ORA-00904: "NUMBER": invalid identifier
SQL> insert into test ("number") values (1);
1 row created.
SQL> select t."number" from test t;
number
----------
1
SQL>
Therefore, I'd suggest you to check table description and try with what you see; maybe it is as simple as
select b."number" ...
If that's the case, it is more than obvious that doing something because you can do it doesn't mean that you should do it. Avoid such things, never enclose Oracle object names into double quotes, use defaults.

Leave column out of Oracle insert statement

I have an insert statement that I am trying to run against an Oracle database. The insert statement is very simple, and I only want to insert a value into one column. The table itself has more than one column, but I am only interested in filling one of the columns with data. The format of my query is similar to the one below:
insert into myTable (col1) Values (val1)
However, this throws the following error:
ORA-00904: "col1": invalid identifier
I've checked to make sure that the column is named correctly, and my only other thought is that something is wrong with my syntax. There are no constraints on the table such as primary keys. Is it possible to only insert values into certain columns when executing an insert statement in Oracle?
Check that you didn't quote the column name on creation of the table. If you did, the column name is stored as you quoted it. For example:
create table table1 (
id number(2)
)
has a different column name to this
create table table2 (
"id" number(2)
)
Oracle by default stores the (unquoted) column names in uppercase. Quoted are stored as is.
You can use a DESC table_name to see how the columns are stored.
The following
select id from table1
select iD from table1
select ID from table1
fetch the records, while only
select "id" from table2
will fetch records.
select id from table2
will throw the ORA-00904 : "ID" : invalid identifier error.
You may have inadvertently done the quoting during creation while using tools as established below:
https://community.oracle.com/thread/2349926
Btw: Yes it is possible to insert records for only one column, as long as the other columns do not have a NOT NULL constraint on them.
Actually, I think you may be double quoting the column in the insert statement (not on table creation), although your example is misleading. I guess this because of your error, which says "col1" is invalid, not "COL1" is invalid. Consider this simple test:
SQL> create table mytable
(
col1 varchar2(10)
)
Table created.
SQL> -- incorrect column name, without double quotes
SQL> insert into mytable(col2) values ('abc')
insert into mytable(col2) values ('abc')
Error at line 9
ORA-00604: error occurred at recursive SQL level 1
ORA-06502: PL/SQL: numeric or value error: character string buffer too small
ORA-06512: at line 11
ORA-00904: "COL2": invalid identifier
SQL> -- incorrect column name, with double quotes
SQL> insert into mytable("col2") values ('abc')
insert into mytable("col2") values ('abc')
Error at line 12
ORA-00604: error occurred at recursive SQL level 1
ORA-06502: PL/SQL: numeric or value error: character string buffer too small
ORA-06512: at line 11
ORA-00904: "col2": invalid identifier
SQL> -- correct column name, without double quotes (works)
SQL> insert into mytable(col1) values ('abc')
1 row created.
SQL> -- correct column name, with double quotes (fails)
SQL> insert into mytable("col1") values ('abc')
insert into mytable("col1") values ('abc')
Error at line 18
ORA-00604: error occurred at recursive SQL level 1
ORA-06502: PL/SQL: numeric or value error: character string buffer too small
ORA-06512: at line 11
ORA-00904: "col1": invalid identifier
The last failed insert attempt is what I think you may be doing:
insert into mytable("col1") values ...
based on the error message:
ORA-00904: "col1": invalid identifier
So the solution would simply be remove the double quoting around the column name in the insert.
It's most probably a syntax error
Desc myTable;
insert into myTable (col1) Values ('val1')
Ensure col1 is a valid column in the table, and you're simply not trying to say 'select the left-most column.
edit: Is it possible to only insert values into certain columns when executing an insert statement in Oracle?
Yes if you want to only insert into certain columns then simply specify it
e.g.
insert into myTable (col1, col2, col6) Values ('val1', 'val2', 'val3');
This will only work if the column itself doesn't have a NOT NULL constraint - in which case it will not allow a value to be enetered (unless again there's a default value).

ORA-22905 on setting Count(*) into out param

I've created a sample oracle function to returns the number of records in a table. Here is it
create or replace FUNCTION TEST_COUNT
RETURN NUMBER AS recCount NUMBER;
BEGIN
SELECT COUNT(*) INTO recCount FROM **tableName**;
return recCount;
END TEST_COUNT;
Its' being compiled successfully, but when I called this function in Oracle SQL-Developr using command
SELECT * FROM TABLE (TEST_COUNT());
it threw me the following error.
ORA-22905: cannot access rows from a non-nested table item
22905. 00000 - "cannot access rows from a non-nested table item"
*Cause: attempt to access rows of an item whose type is not known at
parse time or that is not of a nested table type
*Action: use CAST to cast the item to a nested table type
Error at Line: 1 Column: 22
I've followed Oracle error ORA-22905: cannot access rows from a non-nested table item but can't reach the solution. Please suggest what should I do?
Well, you're just calling it wrong. The TABLE() table collection expression is used when the function returns a collection (e.g. from create type x as table of number) that you want to treat as a table so you can join against it, which isn't the case here; you're returning a simple NUMBER.
So just do:
SELECT TEST_COUNT FROM DUAL;

Bulk Update from one table to another

So I tried the bulk update in order to copy values from uemte_id column in pp_terminal table to uemte_id column (null at start) in mm_chip table. These two tables have no columns in common.This is what I used:
declare
type ue_tab is table of
pp_terminal.uemte_id%type;
ue_name ue_tab;
cursor c1 is select uemte_id from pp_terminal;
begin
open c1;
fetch c1 bulk collect into ue_name;
close c1;
-- bulk insert
forall indx in ue_name.first..ue_name.last
update mm_chip set uemte_id = ue_name(indx);
end;
/
And this is the error message I get:
Error report:
ORA-00001: unique constraint (DPOWNERA.IX_AK7_MM_CHIP) violated
ORA-06512: at line 13
00001. 00000 - "unique constraint (%s.%s) violated"
*Cause: An UPDATE or INSERT statement attempted to insert a duplicate key.
For Trusted Oracle configured in DBMS MAC mode, you may see
this message if a duplicate entry exists at a different level.
*Action: Either remove the unique restriction or do not insert the key.
Do you see any obvious misstakes?
What you're trying to do is:
select a row from the first table
update every row in the second table with that value
select another row from the first table
update every row in the second table with that value
and so forth until the loop finishes
I'm guessing that's not what you really want to do. It's failing because you have a unique constraint so you're not allowed to have multiple rows in the second table with the same value.
Below is one way to update each row of one table based on the value of an arbitrary row in a second table, without reusing any rows from the second table. It would perform better if you could do it entirely in SQL, but I couldn't come up with a way to do that.
CREATE TABLE test4 AS
(SELECT LEVEL AS cola, CAST(NULL AS number) AS colb
FROM DUAL
CONNECT BY LEVEL <= 100);
CREATE TABLE test5 AS
(SELECT 100 + LEVEL AS colc
FROM DUAL
CONNECT BY LEVEL <= 99);
DECLARE
CURSOR cur_test4 IS
SELECT *
FROM test4
FOR UPDATE ;
CURSOR cur_test5 IS
SELECT * FROM test5;
r_test5 cur_test5%ROWTYPE;
BEGIN
OPEN cur_test5;
FOR r_test4 IN cur_test4 LOOP
FETCH cur_test5 INTO r_test5;
IF cur_test5%NOTFOUND THEN
EXIT;
END IF;
UPDATE test4
SET colb = r_test5.colc
WHERE CURRENT OF cur_test4;
END LOOP;
CLOSE cur_test5;
END;

Resources