How query from another database that is in another machine/server - oracle

I've been looking for answer to this but I can't seem to find the right answer online and my problem goes like this.
I'm trying to query a set of records from another table which is in an another database installed in a different machine. To make it clearer:
My stored procedure is running on IP: 192.168.XX.X1. I get to retrieve all the information I need in this server but I have another set of information or records that can only be retrieved from IP: 192.168.XX.X2.
I was thinking to achieve something like:
DECLARE
-- given that both queries will only return 1 record
CURSOR IS curSample1
SELECT * FROM Database1.Table1;
colSample curSample1%ROWTYPE;
CURSOR IS curSample2
SELECT * FROM Database2.Table1;
colSample curSample2%ROWTYPE;
vText1 VARCHAR(20);
vText2 VARCHAR(20);
BEGIN
OPEN curSample1;
LOOP
FETCH curSample1 INTO colSample1;
EXIT WHEN curSample1%NOTFOUND;
vText1 := colSample1.Column1;
END LOOP;
CLOSE curSample1;
OPEN curSample2;
LOOP
FETCH curSample2 INTO colSample2;
EXIT WHEN curSample2%NOTFOUND;
vText2 := colSample2.Column2;
END LOOP;
CLOSE curSample2;
dbms_output.put_line(vText1 || ',' || vText2);
END;
Any help you could provide will be much appreciated. Thank you very much.
Note: I'm trying this approach as this is the only way we could possibly do it as of now. Thanks again.

You will have to create a db link between your database 1 and database 2. For creating a database link it is not required to have both databases on the same server. Since in your case the databases are on different server you can start with the following steps.
You need a tns entry (pointing to database 2) in the tnsnames.ora file on your database 1 server. You can check if you have this entry by connecting to SQLPLUS from your database 1 machine to database 2.
sqlplus <username>/<password>#<tnsnames of database2>
If you are able to connect from your database 1 server then you can proceed with the following steps for creating the db link.
CREATE DATABASE LINK <dblink_name> CONNECT TO <username> IDENTIFIED BY <password> USING <tnsnames of database2>
Post this you can test your database link by running the following SQL command.
select * from Table#<dblink_name>;

as i know you cannot query data cross database directly.
1,maybe you can use DBlink or DataSync to let the data which in other database can be query.
2,instead of pl/sql procedure, use other development language to do cross DB process is a good idea(ex independent java program).
3,instead of pl/sql procedure, use Oracle Java Procedure to do this.

Related

How to execute query when oracle starting up?

I have some question.
I want to execute some SQL query when oracle starting up(initialization).
for instance, Linux, Windows, and etc. OS are enable to run program, when computer start up.
anyway, my purpose is executing some query in oracle 11g r1, when oracle starting up.
You could use AFTER STARTUP Triggers.
create or replace trigger
tr_startup_actions
after startup on database
begin
procedure_runing_query(p_arg1);
end;
/
Run the query you need to inside the procedure or within the block if you need it. But, you should decide a way to store the result of the query somewhere. storing it in a table would be better.
here is an example:
CREATE OR REPLACE TRIGGER
manage_service
after startup on database
DECLARE
role VARCHAR(30);
BEGIN
SELECT DATABASE_ROLE INTO role FROM V$DATABASE;
IF role = 'PRIMARY' THEN
DBMS_SERVICE.START_SERVICE('sales_rw');
ELSE
DBMS_SERVICE.START_SERVICE('sales_ro');
END IF;
END;
is this what you need?

How to use synonym of a DBlink in Oracle?

I have created a synonym for a dblink.
create synonym dblink2 for dblink1
But when I query anything using the synonym instead of the dblink, I'm getting connection description for remote database not found error.
SELECT * FROM DUAL#DBLINK2
How do I query using the synonym?Edit: I know that it'll work if I create a view of the table using dblink. But my requirement is the above question.
Unfortunately creation of synonyms for dblinks is not supported. If you read the documentation on synonyms, you will find that the permitted objects for synonyms are only:
Use the CREATE SYNONYM statement to create a synonym, which is an
alternative name for a table, view, sequence, procedure, stored
function, package, materialized view, Java class schema object,
user-defined object type, or another synonym.
The reason why your second query fails is that the synomym you have created is not functioning correctly. It is not being validated properly at creation time, and you can create any sort of incorrect synonyms like that. To verify, just test the following statement:
create synonym dblink3 for no_object_with_this_name;
You will still get a response like this:
*Synonym DBLINK3 created.*
But of course nothing will work via this synonym.
I don't see the point in creating a synonym for the dblink itself. Ideally you create the synonym for the remote table using the dblink.
CREATE DATABASE LINK my_db_link CONNECT TO user IDENTIFIED BY passwd USING 'alias';
CREATE SYNONYM my_table FOR remote_table#my_db_link;
Now, you could query the remote table using the synonym:
SELECT * FROM my_table;
I'm trying to think of the business issue that gets solved by putting a synonym on a db_link, and the only thing I can think of is that you need to deploy constant code that will be selecting from some_Table#some_dblink, and although the table names are constant different users may be looking across different db_links. Or you just want to be able to swap which db_link you are operating across with a simple synonym repoint.
Here's the problem: it can't be done that way. db_link synonyms are not allowed.
Your only solution is to have the code instead reference the tables by synonyms, and set private synonyms to point across the correct db_link. That way your code continues to "Select from REMOTE_TABLE1" and you just can flip which DB_LINK you are getting that remote table from.
Is it a pain to have to set/reset 100+ private synonyms? Yep. But if it is something you need to do often then bundle up a procedure to do it for you where you pass in the db_link name and it cycles through and resets the synonyms for you.
While I understand that this question is 3+ years old, someone might be able to benefit from a different answer in the future.
Let's imagine that I have 4 databases, 2 for production and 2 for dev / testing.
Prod DBs: PRDAPP1DB1 and PRDAPP2DB1
Dev DBs: DEVAPP1DB1 and DEVAPP2DB1
The "APP2" databases are running procedures to extract and import data from the APP1 databases. In these procedures, there are various select statements, such as:
declare
iCount INTEGER;
begin
insert into tbl_impdata1
select sysdate, col1, col2, substr(col3,1,10), substr(col3,15,3)
from tbl1#dblink2; -- Where dblink2 points to DEVAPP1DB1
...
<more statements here>
...
EXCEPTION
<exception handling code here>
end;
Now that is okay for development but the dblink2 constantly needs to be changed to dblink1 when deploying the updated procedure to production.
As it was pointed out, synonyms cannot be used for this purpose.
But instead, create the db links with the same name, different connection string.
E.g. on production:
CREATE DATABASE LINK "MyDBLINK" USING 'PRDAPP1DB1';
And on dev:
CREATE DATABASE LINK "MyDBLINK" USING 'DEVAPP1DB1';
And then in the procedures, change all "#dblink1" and "#dblink2" to "#mydblink" and it all should be transparent from there.
If you are trying to have the DB link accessible for multiple schemas (users) the answer is to create a public db link
example:
CREATE PUBLIC DATABASE LINK dblink1 CONNECT TO user IDENTIFIED BY password USING 'tnsalias';
After that any schema can issue a:
SELECT * FROM TABLE#dblink1

Weblogic JDBC Connections: multi-statement init SQL

When setting up a data source in WLS we can give it an init SQL statement, which is executed immediately after creation of every connection for this data source.
So far we are using..
SQL ALTER SESSION SET current_schema=user01
.. as we are logging in using an application user02 which has less rights than the owner user01, but we still want the data source to see the schema.
Now we'd like to add some session meta information to the DS connections, for debugging purposes on the DB side. The statements..
DBMS_APPLICATION_INFO.set_client_info('bar');
DBMS_APPLICATION_INFO.set_module('qux', 'garp');
.. allow you to set custom strings as identifiers, which will then show up in colums of V_$SESSION, thus giving the DBA some more information about a DB connection.
My problem
How is it possible to have multi-line init SQL statements? Note that the init SQL syntax expects an SQL command which is preceded by SQL and which does not end in a semicolon ;.
Edit:
What I tried so far is something along the lines of..
begin
execute immediate 'ALTER SESSION SET current_schema=uzms01';
DBMS_APPLICATION_INFO.set_client_info('bar');
DBMS_APPLICATION_INFO.set_module('qux', 'garp');
end;
.. but I keep getting errors. :(
Looks like there was a small syntax irregularity which I did not spot because SQL developer executes it without problems...
The following snippet works (note the parentheses after immediate):
SQL BEGIN
execute immediate('alter session set current_schema=user01');
DBMS_APPLICATION_INFO.set_client_info('my client');
DBMS_APPLICATION_INFO.set_module('my module', 'my action');
END;

ORACLE 11G Data base administration

Dear friends,
I using oracle 11g database, I want to create a number of users. for example username starting from test001 to test100, one by one I do create a all usernames. so this problem I want to create a number of users in a single file( using script) or any of commands kindly guide me! not only creating as well as grant also?
You could try writing SQL-generating SQL.
Try something like this SQL script to get you started:
spool create_100_users.sql
select 'create user user'||rownum||' identified by user'||rownum||';' from dual connect by level < 101;
spool off
#create_100_users
You can do similar SQL to generate grants, etc. Just modify the text in the select statement.

How to check if a database link is valid in Oracle?

I have a main database with only setup data at the headquarter and several databases at different branches.I created a database link for each branch server.
In some case I would like to query all the valid links (as some links could be invalid due to connection problems or anything else),so my question is How to check if the database link is valid without getting in Connection timeout problems. Is there a SQL statement to let the oracle main server do that check and return only the valid database links?
You can verify db link by executing:
select * from dual#my_db_link;
To can create function that verifies db link:
function is_link_active(
p_link_name varchar2
) return number is
v_query_link varchar2(100) := 'select count(*) alive from dual#'||p_link_name;
type db_link_cur is REF CURSOR;
cur db_link_cur;
v_status number;
begin
open cur FOR v_query_link;
loop
fetch cur INTO v_status;
exit when cur%notfound;
dbms_output.put_line('v_status='||v_status);
return v_status;
end loop;
close cur;
exception when others then
close cur;
return 0;
end is_link_active;
Lastly, you can create table my_db_links(id, name, status(0,1)) and update it:
update
my_db_links mdl
set
mdl.status = is_link_active(mdl.name);
I'm not sure you can create a query to check live db links.
One thing you could do is create a table updated by a background process with the list of db links and for each of them a 'last time seen alive' timestamp
Any link could have a problem due to different categories of issues:
invalid link definition: wrong
username, password (if used), service
name
remote account locked
remote db configuration (e.g. sessions per user exceeded)
remote db or host unavailability
network connectivity
Given the changing nature of these failure modes there can't be a dictionary view (for example) that describes the state of the link. An asynchronous process that checks in the background will also stand a chance of being out-of-date. Probably the lightest-weight test you can do is issue a "select sysdate from dual#remote_db" before you need to use the link in your code
You could write an OS level script that performs a tnsping, since db links usually depend on the tnsnames.ora anyway.
You could use WITH FUNCTION and do simple check:
WITH FUNCTION check_dblink(p_dblink IN VARCHAR2) RETURN VARCHAR2 IS
r INT;
BEGIN
EXECUTE IMMEDIATE 'SELECT 1 FROM dual#"' || p_dblink || '"' INTO r;
RETURN 'OK';
EXCEPTION
WITH OTHERS THEN
RETURN SQLERRM;
END;
SELECT check_dblink(db_link), udl.*
FROM user_db_links udl;
As result you will get OK or error message.
I don't know if you managed to get this done, but I wanted to do something like this and check which database links are active. I found this on another forum
Select * from v$dblink
which shows only active dblinks. Again, this will work only if you have permission to access v$dblink.

Resources