ORA-02070: database does not support in this context - oracle

I have a query like
INSERT INTO sid_rem#dev_db
(sid)
select sid from v$session
Now, when i execute this query i get
ORA-02070: database does not support in this context
This error happens only when I insert data from v$session into some remote db. Its working fine for any other table.
Anyone know why this issue and any workaround for this?

Works using gv$session instead of v$session:
INSERT INTO sid_rem#dev_db(sid)
select sid from gv$session;
gv$ views are global views, that is, they are not restricted to one node(instance), but see the entire database(RAC). v$ views are subviews of gv$.
Searching on the internet I found this has something to do with distributed transactions.
Thread on ora-code.com

Late answer but might still be useful. I've found this error occurs when trying to select from system views across a database link where the system view contains columns of type LONG. If the query can be reworded to avoid the LONG columns these joins will work fine.
Example:
SELECT dc_prod.*
FROM dba_constraints#prod_link dc_prod
INNER JOIN dba_constraints dc_dev
ON (dc_dev.CONSTRAINT_NAME = dc_prod.CONSTRAINT_NAME)
will fail with an ORA-02070 due to accessing the LONG column SEARCH_CONDITION, but
SELECT dc_prod.*
FROM (SELECT OWNER,
CONSTRAINT_NAME,
CONSTRAINT_TYPE,
TABLE_NAME,
-- SEARCH_CONDITION,
R_OWNER,
R_CONSTRAINT_NAME,
DELETE_RULE,
STATUS,
DEFERRABLE,
DEFERRED,
VALIDATED,
GENERATED,
BAD,
RELY,
LAST_CHANGE,
INDEX_OWNER,
INDEX_NAME,
INVALID,
VIEW_RELATED
FROM dba_constraints#prod_link) dc_prod
INNER JOIN (SELECT OWNER,
CONSTRAINT_NAME,
CONSTRAINT_TYPE,
TABLE_NAME,
-- SEARCH_CONDITION,
R_OWNER,
R_CONSTRAINT_NAME,
DELETE_RULE,
STATUS,
DEFERRABLE,
DEFERRED,
VALIDATED,
GENERATED,
BAD,
RELY,
LAST_CHANGE,
INDEX_OWNER,
INDEX_NAME,
INVALID,
VIEW_RELATED
FROM dba_constraints) dc_dev
ON (dc_dev.CONSTRAINT_NAME = dc_prod.CONSTRAINT_NAME)
works fine because the LONG column SEARCH_CONDITION from DBA_CONSTRAINTS is not accessed.
Share and enjoy.

I don't know why this is happening, it's probably in the documentation somewhere but my Oracle-Docs-Fu seems to have deserted me today.
One possible work-around is to use a global temporary table
SQL> create table tmp_ben ( sid number );
Table created.
SQL> connect schema/pw#db2
Connected.
SQL> create table tmp_ben ( sid number );
Table created.
SQL> insert into tmp_ben#db1 select sid from v$session;
insert into tmp_ben#db1 select sid from v$session
*
ERROR at line 1:
ORA-02070: database does not support in this context
SQL> create global temporary table tmp_ben_test ( sid number );
Table created.
SQL> insert into tmp_ben_test select sid from v$session;
73 rows created.
SQL> insert into tmp_ben#db1 select * from tmp_ben_test;
73 rows created.

Related

Is it possible to set default ORACLE dblink for session and avoid #dblink_name suffixes

I have an Oracle database with a couple of public dblinks for various customers. All linked databases for all customers are identical. Also I have a schema on my host machine only, where I stored DB views with some data retrieval logic.
Currently, if I want to retrieve the same data from various customers, I have to create separate almost identical views for every client:
CREATE VIEW my_view_for_cliet1 AS
SELECT *
FROM table1#dblink1;
CREATE VIEW my_view_for_cliet2 AS
SELECT *
FROM table1#dblink2
Is it possible to set default dblink for session (or something similar) and have only one DB view without explicit dblink, for example:
CREATE VIEW my_view AS
SELECT *
FROM table1;
-- below I want to retrieve data from 3rd client
ALTER SESSION SET DEFAULT DBLINK dblink3;
SELECT * FROM my_view;
P.S. I have only SELECT rights on linked machines so I can't create any views or other objects.
No, that is not possible. Every reference to a dblink must be explicit.
Note that each of the other solutions presented (so far) can give the appearance of what you're asking, but still require explicit dblink references in all of the actual views and thus the same DDL changes for every new link and/or client user. There's no way to avoid creating those individual views or explicit references at some level (which is what I believe you were asking), even if you hide them somewhat from the user.
I'd suggest using synonyms, and set up a procedure to change them all at once, e.g.
create or replace procedure SET_DBLINK ( target_link IN VARCHAR2 ) is
begin
execute immediate 'create or replace synonym TABLE1 for TABLE1#' || target_link;
execute immediate 'create or replace synonym TABLE2 for TABLE2#' || target_link;
-- ...etc...
end;
/
That way you could do:
exec SET_DBLINK('dblink3');
select * from table1;
You'd probably want to add validation and exception handling to the procedure, but I left it simple for readability.
For example, user manager
CREATE OR REPLACE VIEW manager.example1 (
column1,
column2
)
AS
select 1, user from dual#dblink1
where 'SCOTT'=user
union all
select 2, user from dual#dblink2
where 'MANAGER'=user
union all
select 3, user from dual#dblink3
where 'HR'=user;
grant select on example1 to scott;
grant select on example1 to hr;
select * from example1;
==>
COLUMN1 COLUMN2
-------------------------------------------- ------------------------------------
2 MANAGER
user scott
create synonym example1 for manager.example1;
select * from example1;
==>
COLUMN1 COLUMN2
-------------------------------------------- ------------------------------------
1 SCOTT
user hr
create synonym example1 for manager.example1;
select * from example1;
==>
COLUMN1 COLUMN2
-------------------------------------------- ------------------------------------
3 HR

how to get select statement query which was used to create table in oracle

I created a table in oracle like
CREATE TABLE suppliers AS (SELECT * FROM companies WHERE id > 1000);
I would like to know the complete select statement which was used to create this table.
I have already tried get_ddl but it is not giving the select statement. Can you please let me know how to get the select statement?
If you're lucky one of these statements will show the DDL used to generate the table:
select *
from gv$sql
where lower(sql_fulltext) like '%create table suppliers%';
select *
from dba_hist_sqltext
where lower(sql_text) like '%create table%';
I used the word lucky because GV$SQL will usually only have results for a few hours or days, until the data is purged from the shared pool. DBA_HIST_SQLTEXT will only help if you have AWR enabled, the statement was run in the last X days that AWR is configured to hold data (the default is 8), the statement was run after the last snapshot collection (by default it happens every hour), and the statement ran long enough for AWR to think it's worth saving.
And for each table Oracle does not always store the full SQL. For security reasons, DDL statements are often truncated in the data dictionary. Don't be surprised if the text suddenly cuts off after the first N characters.
And depending on how the SQL is called the case and space may be different. Use lower and lots of wildcards to increase the chance of finding the statement.
TRY THIS:
select distinct table_name
from
all_tab_columns where column_name in
(
select column_name from
all_tab_columns
where table_name ='SUPPLIERS'
)
you can find table which created from table

No data found error even though data exists

The problem I'm having is similar to that in this question and this question, but in those cases there was a char vs varchar issue.
I'm trying to select the first partition for my table from user_tab_partitions; I've tried it two ways:
SELECT partition_name, high_value into V_PARTITION_NAME, V_HIGH_VALUE from user_tab_partitions where table_name like 'MYTABLE' and partition_position=1;
SELECT partition_name, high_value into V_PARTITION_NAME, V_HIGH_VALUE from user_tab_partitions where table_name like 'MYTABLE' and rownum<=1 order by partition_position;
Either way, the code works fine in SQL Developer but when I run it as part of a stored procedure, I get the NO_DATA_FOUND exception. There's a check prior to this code that ensures it doesn't run unless at least two partitions exist.

Why is Oracle losing data during commit?

I have a fairly standard SQL Query as follows:
TRUNCATE TABLE TABLE_NAME;
INSERT INTO TABLE_NAME
(
UPRN,
SAO_START_NUMBER,
SAO_START_SUFFIX,
SAO_END_NUMBER,
SAO_END_SUFFIX,
SAO_TEXT,
PAO_START_NUMBER,
PAO_START_SUFFIX,
PAO_END_NUMBER,
PAO_END_SUFFIX,
PAO_TEXT,
STREET_DESCRIPTOR,
TOWN_NAME,
POSTCODE,
XY_COORD,
EASTING,
NORTHING,
ADDRESS
)
SELECT
BASIC_LAND_AND_PROPERTY_UNIT.UPRN,
LAND_AND_PROPERTY_IDENTIFIER.SAO_START_NUMBER AS SAO_START_NUMBER,
LAND_AND_PROPERTY_IDENTIFIER.SAO_START_SUFFIX AS SAO_START_SUFFIX,
LAND_AND_PROPERTY_IDENTIFIER.SAO_END_NUMBER AS SAO_END_NUMBER,
LAND_AND_PROPERTY_IDENTIFIER.SAO_END_SUFFIX AS SAO_END_SUFFIX,
LAND_AND_PROPERTY_IDENTIFIER.SAO_TEXT AS SAO_TEXT,
LAND_AND_PROPERTY_IDENTIFIER.PAO_START_NUMBER AS PAO_START_NUMBER,
LAND_AND_PROPERTY_IDENTIFIER.PAO_START_SUFFIX AS PAO_START_SUFFIX,
LAND_AND_PROPERTY_IDENTIFIER.PAO_END_NUMBER AS PAO_END_NUMBER,
LAND_AND_PROPERTY_IDENTIFIER.PAO_END_SUFFIX AS PAO_END_SUFFIX,
LAND_AND_PROPERTY_IDENTIFIER.PAO_TEXT AS PAO_TEXT,
STREET_DESCRIPTOR.STREET_DESCRIPTOR AS STREET_DESCRIPTOR,
STREET_DESCRIPTOR.TOWN_NAME AS TOWN_NAME,
LAND_AND_PROPERTY_IDENTIFIER.POSTCODE AS POSTCODE,
BASIC_LAND_AND_PROPERTY_UNIT.GEOMETRY AS XY_COORD,
BASIC_LAND_AND_PROPERTY_UNIT.X_COORDINATE AS EASTING,
BASIC_LAND_AND_PROPERTY_UNIT.Y_COORDINATE AS NORTHING,
decode(SAO_START_NUMBER,null,null,SAO_START_NUMBER||SAO_START_SUFFIX||' ')
||decode(SAO_END_NUMBER,null,null,SAO_END_NUMBER||SAO_END_SUFFIX||' ')
||decode(SAO_TEXT,null,null,SAO_TEXT||' ')
||decode(PAO_START_NUMBER,null,null,PAO_START_NUMBER||PAO_START_SUFFIX||' ')
||decode(PAO_END_NUMBER,null,null,PAO_END_NUMBER||PAO_END_SUFFIX||' ')
||decode(PAO_TEXT,null,null,'STREET RECORD',null,PAO_TEXT||' ')
||decode(STREET_DESCRIPTOR,null,null,STREET_DESCRIPTOR||' ')
||decode(POST_TOWN,null,null,POST_TOWN||' ')
||Decode(Postcode,Null,Null,Postcode) As Address
From (Land_And_Property_Identifier
Inner Join Basic_Land_And_Property_Unit
On Land_And_Property_Identifier.Uprn = Basic_Land_And_Property_Unit.Uprn)
Inner Join Street_Descriptor
On Land_And_Property_Identifier.Usrn = Street_Descriptor.Usrn
Where Land_And_Property_Identifier.Postally_Addressable='Y';
If I run this query in SQL Developer, it runs fine with 1.8million features inserted (select count(*) from TABLE_NAME within the session confirms this).
But when I run the commit, the data disappears! select count(*) from TABLE_NAME now returns 0 results.
We've done a number of things to try and see what's going on:
During the Truncate, tablespace is freed up, and during the insert its filled again. There is no change during the commit. This implies the data is in the database.
If I do the exact same query but with and rownum < 100 appended to the end, the commit works. Same with 1000.
I found this question: oracle commit kills and had our DBA try the "SQL Trace". This produced a >4GB file which when parsed with TKPROF produced a 120 page report but we don't know how to read it and there's nothing obviously wrong in there.
Our error logs have nothing in them. And obviously no error during the commit itself.
There's a trigger/sequence which does increment by 1.8million during the process.
I've repeated this about 4 times now, but the result is always the same.
So my question is simple - what's happening to the data during the commit? How can we find out? Thanks.
Note: This has run fine in the past so I don't believe there's anything wrong with the SQL per-se.
Edit: Issue resolved by recreating the table from scratch. Now when I insert it only takes 500 seconds compared to the previous 2000. And commiting is instantaneous; when it was broken the commit took 4000 seconds!
I still have no idea why it happened though.
For those asking, the Create Table syntax:
CREATE TABLE TABLE_NAME
(
ADDRESS VARCHAR2(4000),
UPRN NUMBER(12),
SAO_START_NUMBER NUMBER(4),
SAO_START_SUFFIX VARCHAR2(1),
SAO_END_NUMBER NUMBER(4),
SAO_END_SUFFIX VARCHAR2(1),
SAO_TEXT VARCHAR2(90),
PAO_START_NUMBER NUMBER(4),
PAO_START_SUFFIX VARCHAR2(1),
PAO_END_NUMBER NUMBER(4),
PAO_END_SUFFIX VARCHAR2(1),
PAO_TEXT VARCHAR2(90),
STREET_DESCRIPTOR VARCHAR2(100),
TOWN_NAME VARCHAR2(30),
POSTCODE VARCHAR2(8),
XY_COORD MDSYS.SDO_GEOMETRY,
EASTING NUMBER(7),
NORTHING NUMBER(7)
)
CREATE INDEX TABLE_NAME_ADD_IDX ON TABLE_NAME (ADDRESS);
Do you still lose the data if you wrap the transaction in an anonymous block?
My guess is that you are opening two SQL windows in SQL Developer and that means two separate sessions. i.e. Running SQL code in window 1 and doing commit; in window 2 will not commit changes done in window 1.
Truncate table does an implicit commit. So the table will be empty until insert + commit finishes.
begin
execute immediate 'truncate table table_name reuse storage'; --use "reuse" if you know the data will be of similar size
-- implicit commit has occured and the table is empty for all sessions
insert into table_name (lots)
select lots from table2;
commit;
end;
You should use truncate with reuse storage, so that the database doesn't go a free all the blocks just to acquire the same number of blocks in the insert.
If you want/need to have the data available at all times a better (but longer) method is
begin
savepoint letsgo;
delete from table_name;
insert into table_name (lots)
select lots from table2;
commit;
exception
when others then
rollback to letsgo;
end;
Probably you had a trigger which you didn't noticed. Can you check the oracle's recyclebin table which might be storing the history of your dropped table and trigger?
Select * from recyclebin;
References : http://www.oraclebin.com/2012/12/recyclebinflashback.html

Oracle--Error(Refereence to object_id)

SELECT object_id from dbname.tablename
This query has to be executed against oracle 11g.I get errors when i execute this.
I do a migration from sybase to oracle and in oracle this query fails.
What could be the problem. Please suggest a solution
"What could be the problem."
All sorts of things. Since you failed to state what errors you're getting, we can only guess, e.g.:
Table not found
No SELECT privilege on table
dbname not a valid schema
object_id not a column in the table
Not connected to a running oracle instance
Trying to run the statement in an environment that doesn't understand SQL
etc, etc, ...
If all you want is to check that the table exists, you could do this:
SELECT 1 FROM dba_tables WHERE owner = 'DBNAME' AND table_name = 'TABLENAME';
If you want to check that you can query the table, you could do this:
SELECT 1 FROM schemaname.tablename WHERE 1=0;
If you want to check if the table has any rows, you could do this:
SELECT 1 FROM schemaname.tablename WHERE ROWNUM <= 1;
What you will do with the result. If you only want a unique id for a row, yo can user SELECT ROWID FROM dbname.tablename!

Resources