TYPE v_id IS table of table#dblink.column%type; - oracle

I have table 'test' in schema A and from schema B I want to run the test query.
so created DBlink to A.test and dblink name 'dbl_test' .
now, I am able to query as
select * from test#dbl_test;
but when I try to use TYPE v_id IS TABLE OF test#dbl_test.id%TYPE; in plsql procedure block with cursor, it is giving errors as must declare and dbl_test is another database and not able to access.
When I query the select statement it is working why not for TYPE?

Put the column before the #:
TYPE v_id IS TABLE OF test.id#dbl_test%TYPE;

Database links are used to link two databases, not schemas.
In your case it is unclear if you really need a database link. Are your two schemas in the same database? If they are, you need only give the relevant rights to schema B and he will be able to reference schema A's datatype. I Think GRANT SELECT ON A.TEST TO B should be sufficient to reference its datatype.
Edit: it is actually possible to reference a remote datatype (I didn't know!) See #jonearles' answer.

Related

Creating a Cross-Schema Spatial Index in Oracle impossible with single user?

The oracle documentation here:
https://docs.oracle.com/en/database/oracle/oracle-database/21/spatl/indexing-querying-spatial-data.html#GUID-8E6AE949-758B-4A5E-9453-CC3D00647497
Talks about creating an index in schema A with user B
CREATE INDEX t1_spatial_idx on A.T1(geometry) INDEXTYPE IS mdsys.spatial_index_v2;
This, however, requires you to insert into user_sdo_geom_metadata. I'm trying to do this as one single connected user and that seems impossible. Let's say I'm user B, whenever I insert into user_sdo_geom_metadata the resulting changes won't get picked up by the view that the CREATE INDEX statement uses, which is ALL_SDO_GEMO_METADATA. As an example try:
INSERT INTO user_sdo_geom_metadata (table_name,column_name,diminfo,srid) VALUES
('T1','geometry', sdo_dim_array(sdo_dim_element('X',-180.0,180.0, 0.005),sdo_dim_element('Y',-90.0,90.0, 0.005)), 4326);
There is no way to specify the schema to get this into the correct format. In fact, if the T1 table here doesn't exist in your schema then nothing appears in ALL_SDO_GEMO_METADATA. I've tried
ALTER SESSION SET CURRENT_SCHEMA = 'A'
But that doesn't work. I'm trying to use Schemas as a way of collating together self-contained groupings of tables, views, indexes, etc. like you would in a normal database. In other words, I'm trying to use them like actual schemas. Oracle makes this challenging at the best of times, and I don't want to manage separate logins for each schema, but I can't see how it's possible to do this for spatial indexes.
Well, this was an epic struggle but got there in the end. The only way to create the metadata AND the index as another user is to create a stored procedure that does the INSERT but it's not as easy as just following the instructions, you have to call the package proc directly like so:
CREATE OR REPLACE PROCEDURE "<user name>".ADDMETADATA(
schema_name VARCHAR2, table_name VARCHAR2, column_name VARCHAR2, srid NUMBER, bounds MDSYS.SDO_DIM_ARRAY)
IS
BEGIN
mdsys.sdo_meta.insert_all_sdo_geom_metadata(schema_name, table_name, column_name, bounds, srid);
END ADDMETADATA;
Which almost certainly isn't supported but the standard way is broken so you have to. You then need to create this in every single new schema along with giving the schema user CREATE TABLE and CREATE SEQUENCE permissions. So to create a schema programmatically and have it all work boils down to the following steps:
CREATE the Schema/User and set the tablespace
GRANT CREATE SEQUENCE to the Schema/User
GRANT CREATE TABLE to the Schema/User
ALTER the quota on the TABLESPACE for the Schema/User
CREATE the stored proc above
CALL the stored proc
CALL create INDEX
Painfully long-winded but works. The whole schema-as-user thing remains a terrible idea, most databases can do all this with one SQL statement.

Using oracle seq generator in Informatica Mapping [duplicate]

I use SQL developer and i made a connection to my database with the system user, after I created a user and made a another connection with that user with all needed privileges.
But when I try to proceed following I get the SQL Error
ORA-00942 table or view does not exist.:
INSERT INTO customer (c_id,name,surname) VALUES ('1','Micheal','Jackson')
Because this post is the top one found on stackoverflow when searching for "ORA-00942: table or view does not exist insert", I want to mention another possible cause of this error (at least in Oracle 12c): a table uses a sequence to set a default value and the user executing the insert query does not have select privilege on the sequence. This was my problem and it took me an unnecessarily long time to figure it out.
To reproduce the problem, execute the following SQL as user1:
create sequence seq_customer_id;
create table customer (
c_id number(10) default seq_customer_id.nextval primary key,
name varchar(100) not null,
surname varchar(100) not null
);
grant select, insert, update, delete on customer to user2;
Then, execute this insert statement as user2:
insert into user1.customer (name,surname) values ('michael','jackson');
The result will be "ORA-00942: table or view does not exist" even though user2 does have insert and select privileges on user1.customer table and is correctly prefixing the table with the schema owner name. To avoid the problem, you must grant select privilege on the sequence:
grant select on seq_customer_id to user2;
Either the user doesn't have privileges needed to see the table, the table doesn't exist or you are running the query in the wrong schema
Does the table exist?
select owner,
object_name
from dba_objects
where object_name = any ('CUSTOMER','customer');
What privileges did you grant?
grant select, insert on customer to user;
Are you running the query against the owner from the first query?
Case sensitive Tables (table names created with double-quotes) can throw this same error as well. See this answer for more information.
Simply wrap the table in double quotes:
INSERT INTO "customer" (c_id,name,surname) VALUES ('1','Micheal','Jackson')
You cannot directly access the table with the name 'customer'. Either it should be 'user1.customer' or create a synonym 'customer' for user2 pointing to 'user1.customer'. hope this helps..
Here is an answer: http://www.dba-oracle.com/concepts/synonyms.htm
An Oracle synonym basically allows you to create a pointer to an object that exists somewhere else. You need Oracle synonyms because when you are logged into Oracle, it looks for all objects you are querying in your schema (account). If they are not there, it will give you an error telling you that they do not exist.
I am using Oracle Database and i had same problem. Eventually i found ORACLE DB is converting all the metadata (table/sp/view/trigger) in upper case.
And i was trying how i wrote table name (myTempTable) in sql whereas it expect how it store table name in databsae (MYTEMPTABLE). Also same applicable on column name.
It is quite common problem with developer whoever used sql and now jumped into ORACLE DB.
in my case when i used asp.net core app i had a mistake in my sql query. If your database contains many schemas, you have to write schema_name before table_name, like:
Select * from SCHEMA_NAME.TABLE_NAME...
i hope it will helpful.

how to get the DDL of a table with different schema

I have few databases and all the databases have the same tables (i.e. table names). Now i want to get the DDL of the table with different schema.
Use the dbms_metadata package to get the DDL of any object of the DB.
SELECT
DBMS_METADATA.GET_DDL('<Object type>', '<Object name>', '<object schema>')
FROM
DUAL; -- How to
SELECT
DBMS_METADATA.GET_DDL('TABLE', 'MY_TABLE', 'MY_SCHEMA')
FROM
DUAL; -- In your case use something like this
Also, You can format the output using dbms_metadata.set_transform_param.
See Oracle documentation for more information on it.
Cheers!!

How to find all tables updated by a particular plsql method

Is there any way to find all which tables are (potentially) updated by a particular PLSQL method, other than by code inspection?
No, not really.
ALL_DEPENDENCIES lists the tables statically referenced by a PL/SQL package but that will include both tables read and tebles updated, and it's for the entire package, not just a single procedure. Tables updated via dynamic SQL are not listed. Also, a procedure can call procedures outside the package, and they can in turn update additional tables.
Maybe query the all_source table:
select * from all_source
where name = 'procedure_name'
and upper(text) like upper('%update TABLE_NAME%');
While not exactly what you want, it will show what procedures, functions or packages contain the table_name right after an UPDATE (assuming they are on the same line).

Temporary table in Oracle like SQL Server

In SQL Server one could do something like the following
declare #t as table(id int)
insert into #t values(1)
insert into #t values(2)
delete from #t where id=1
Is there an equivalence of this in Oracle without creating a physical table. Now, I used to create physical table to do this and delete later.
I have gone to this links How to create a temporary table in Oracle but that's 2010 and the reference link mentioned Oracle 8i. Is this still the situation with Oracle 10g and 11g? Another link I have visited is Constructing a temporary table in Oracle SQL
Thanks
CREATE GLOBAL TEMPORARY TABLE admin_work_area
(startdate DATE,
enddate DATE,
class CHAR(20))
ON COMMIT DELETE ROWS;
This statement creates a temporary table that is transaction specific.
For details use below link:
http://docs.oracle.com/cd/B28359_01/server.111/b28310/tables003.htm#i1006400
In most cases you do not need it. In Oracle when you need temporary table then "your design is wrong". Do not try to rewrite MS SQL pattern into Oracle which exact wording. Where you use temporary table in MS SQL you use in Oracle CTE(nested subquery, query factoring) a CURSOR or some PL/SQL construct.
The temporary table is not what you need. It's just a tool you use to achieve some goal. In Oracle you should use other tools.
Use an Associative Array :)
declare
type temp_rec is record(v integer);
type temp_table is table of temp_rev indexed by pls_integer;
my_temp_table temp_table;
begin
-- Here you can do do your stuff :)
end
/

Resources