When connecting to Oracle the JDBC driver identifies itself as "JDBC Thin Client" to Oracle (in v$session as the 'program'). There is also a 'ClientInfo' column in v$session that might be used for this, but it's always empty.
We have a need to identify different applications connecting to Oracle (which are running on the same host, so the 'machine' column in v$session is all the same), so is it possible to change how the Oracle JDBC Thin Client driver identifies itself (so we could put the application name in, for example)?
Or is there a recommended way to do this? One restriction is that we're doing this within Struts for some of the applications, which is handling the connection setup internally.
[Identical to this answer]
java.util.Properties props = new java.util.Properties();
props.setProperty("password","mypassword");
props.setProperty("user","myusername");
props.put("v$session.osuser", System.getProperty("user.name").toString());
props.put("v$session.machine", InetAddress.getLocalHost().getCanonicalHostName());
props.put("v$session.program", "My Program Name");
DriverManager.registerDriver (new oracle.jdbc.OracleDriver());
Connection conn=
DriverManager.getConnection("jdbc:oracle:thin:#myhostname:1521:mysid", props);
SQL>select username,osuser,program,machine
from v$session
where username = 'ROB';
USERNAME OSUSER PROGRAM MACHINE
--------- ----------- ------------------ -----------
ROB rmerkw My Program Name machine
At application level you can use the following methods to set client_info, module and action in v$session:
dbms_application_info.set_client_info
dbms_application_info.set_module
dbms_application_info.set_action
There is also an Oracle function:
dbms_application_info.set_client_info('Client Info');
which sets the ClientInfo column in v$session.
Related
I have some queries against a Sybase database that after some changes in our Java (JDBC) code are failing to execute because the database is returning an error message where it demands we provide the owner in front of the table name but that is something I would prefer to provide in a single place in our configuration. We are using ASE 16.
For example, we had a query like "SELECT * FROM table_name" that will not work anymore unless we specify "SELECT * FROM database_name..table_name"
I think there should be a simple answer for this but I am struggling to find one, thank you in advance.
I am trying to use liquibase for database changes(we are using oracle) and one of the requirements our DBA put forward was to log the ospid and db session id of the jdbc connection so that they can kill it manually should the need arise. I looked through the java.sql.Connection interface and it doesn't seem to be an option available to retrive those values from jdbc connection. Did i miss something ? I would very much appreciate if someone can point out a way to do this. Thanks in advance
You can get the SID and the OS process ID of the current session through a query:
SELECT s.sid, p.spid
FROM v$session s
JOIN v$process p ON p.addr = s.paddr
WHERE sid=sys_context('USERENV','SID') ;
You DBA has to grant you the access to V$SESSION and V$PROCESS.
However, I don't really understand the requirement. If a session is causing problems the DBA is the first to know which one through Oracle Enterprise Manager.
As per my understanding
If you execute the following query from your JDBC connection, it will give you the information you need
SELECT s.sid, s.serial#, p.spid, s.osuser, s.program FROM v$session s, v$process p WHERE p.addr = s.paddr and s.sid in (select distinct sid from v$mystat)
There is nothing in the JDBC API itself to get this information. You will need to use either driver-specific extensions, or query the information, as shown by the other answers.
Today, me too got into the situation to find which thread is running with which Oracle session id. Basically, I am using the connection pool, to get connection in multithreads, and was doing write I/O to a global temp table (GTT), in each thread. The data written in one thread would not be visible to other thread if the session ids are different.
So, while doing that I got a need to know which thread (having its own connection) is using which SID. I found that it is possible by sending tag from Java side in setClientInfo and then we can see in DB query select module, sid from v$session. Actual steps would be:
In the java side, after getting the connection, set the client info
Connection con = dbcpDs.getConnection();
con.setClientInfo("E2E_CONTEXT.MODULE","threadid");
Then run the code and in the db side while it is running you can query like
select module, sid from v$session
And we know which java thread, connection mapped to which Oracle SID. Now from java side we can query the v$session with where module ="threadid" and get it at runtime in java as well!
I just started to use Spark-SQL to load data from a H2 database, here is what I did following the Spark-SQL document:
>>> sqlContext = SQLContext(sc)
>>> df = sqlContext.load(source="jdbc",driver="org.h2.Driver", url="jdbc:h2:~/test", dbtable="RAWVECTOR")
But it didn't work and gave errors, I think the problem is that the username and password are not specified in the function.
This is parameters from the document from Spark-SQL 1.3.1:
url
The JDBC URL to connect to.
dbtable
The JDBC table that should be read. Note that anything that
is valid in a FROM clause of a SQL query can be used. For example,
instead of a full table you could also use a subquery in
parentheses.
driver
The class name of the JDBC driver needed to connect to this
URL. This class with be loaded on the master and workers before
running an JDBC commands to allow the driver to register itself with
the JDBC subsystem.
partitionColumn, lowerBound, upperBound, numPartitions
These options must all be specified if any of them is specified. They describe how to partition the table when reading in parallel from multiple workers. partitionColumn must be a numeric column from the table in question.
But I didn't find any clue how to pass the database user name and password to the sqlContext.load function.
Any one has similar case or clues?
Thanks.
I figured it out. Just do
df = sqlContext.load(
source="jdbc",driver="org.h2.Driver",
url="jdbc:h2:tcp://localhost/~/test?user=sa&password=1234",
dbtable="RAWVECTOR"
)
And when you create the database, use same pattern:
conn = DriverManager.getConnection(
"jdbc:h2:tcp://localhost/~/"+dbName+"?user=sa&password=1234", null, null
);
And, here is a blog about how to use the API.
I have 2 connections with different tables in sqldeveloper.
let's say:
ConnectionA with tables: A,B,C
ConnectionB with tables: D,E,F
Now I want to have a query that looks like this:
select aa.name,dd.id
from A aa,D dd;
How can i do this?
If you want to query objects in two different databases using a single SQL statement, you would need to create a database link between the two databases. A database link is an object that resides in the database and is independent of the query tool. In database A, for example, you could create the database link
CREATE DATABASE LINK to_b
CONNECT TO username IDENTIFIED BY password
USING tns_alias_on_a_pointing_to_b
And then when you connect to A, you could do something like
SELECT aa.name, dd.id
FROM a aa,
d#to_b dd
WHERE aa.some_key = dd.some_key
Apparently TOAD Data Point supports Cross-Connection Queries , see:
http://dev.toadfordataanalyst.com/webhelp/Content/Query_Builder/Create_CrossConnection_Queries.htm
Also Oracle SQL Developer seems to support something similar. (see this blog post: Cross Connection Queries)
I found this helpful and to the point of the OP question for Oracle 11g rel 2 and later: http://www.dba-oracle.com/t_how_create_database_link.htm . Basically, right-click on the connection in the Connections pane in SQL Developer, click Properties, and you get the hostname, port, and service name that you can plug into the "USING" part of the CREATE DATABASE LINK statement. Whether you put in Service Name or SID I assume depends on which you used in your connection. example:
create public database link
mylink
connect to
remote_username
identified by
mypassword
using 'myserver:1521/MYSID';
I'd like to set default database schema in Oracle Connection URL
jdbc:oracle:thin:#<server>:<port1521>:<sid>
My sample SQL statement:
select monkey_name from animals.monkey
I need to query database without schema prefix animals. i.e. when I run this statement
select monkey_name from monkey
it will use animals schema by default.
What do I need to specify in connection URL above get such effect?
Thanks.
You can't put anything in the connection URL.
In Oracle each user has their own schema (even if doesn't contain any objects) and that is their default schema. Once logged in/connected, they can change their default schema with an
ALTER SESSION SET CURRENT_SCHEMA=animals
So you'd need to do the extra statement after connecting.
It is possible to have a logon trigger on the user and/or database that will run this when they log in. I'd personally prefer an explicit statement when an application connects.
If you use C3PO you can make it do it when it checks the connection out.
As properties:
c3p0.preferredTestQuery=alter session set current_schema=animals
c3p0.testConnectionOnCheckout=true
As Java code:
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setPreferredTestQuery("alter session set current_schema=animals");
dataSource.setTestConnectionOnCheckout(true);
Downside is this will happen every time the connection is taken out of the pool.
If you are using a JDBC connection yourself you could just do:
Class.forName("oracle.jdbc.driver.OracleDriver");
Connection connection = getConnection("jdbc:oracle:thin:#//server:1521/instance", "username", "password");
connection.createStatement().execute("alter session set current_schema=animals"));
What about the use of synonyms?
create synonym monkey for animals.monkey;
select monkey_name from monkey
You can create a trigger using connection DB user to change the current schema.
create or replace trigger SET_SCHEMA_AFTER_LOGON
after logon on database
begin
execute immediate 'alter session set CURRENT_SCHEMA=animals';
end SET_SCHEMA_AFTER_LOGON;
Since Java 1.7 there is a setSchema method on java.sql.Connection.
In the Oracle's oracle.jdbc.driver.PhysicalConnection implementation this method execute the alter session set current_schema = ? statement.