Default Schema in Oracle Connection URL - oracle

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.

Related

ERROR: cannot execute nextval() in a read-only transaction - PostgreSQL

I can see internal server error on my app developed on spring mvc, using wildfly as the webserver and database is PostgreSQL. What does this exception mean?
ERROR: cannot execute nextval() in a read-only transaction
It was working all fine before. I tried to look for the solution here on stackoverflow but didn't find anything that could fix this issue.
The function nextval() is used to increment a sequence, which modifies the state of the database.
You get that error because you are in a read-only transaction. This can happen because
You explicitly started a read-only transaction with START TRANSACTION READ ONLY or similar.
The configuration parameter default_transaction_read_only is set to on.
You are connected to a streaming replication standby server.
If default_transaction_read_onlyis set to on, you can either start a read-write transaction with
START TRANSACTION READ WRITE;
or change the setting by editing postgresql.conf or with the superuser command
ALTER SYSTEM SET default_transaction_read_only = off;
As others have pointed out nextval() actually updates the database to get a new sequence, so can't be used in a transaction that is marked as read only.
As you're using Spring I suspect this means that you're using the spring-transaction support. If you're using annotation based transaction support, then you'd get a read only transaction if you have
#Transactional(readOnly=true)
That means that when spring starts the transaction it will put it into read only mode.
Remove the readOnly=true bit and a regular writable transaction is created instead.
Spring transaction control at http://docs.spring.io/spring-framework/docs/4.2.x/spring-framework-reference/html/transaction.html
I means exactly what it says, here is example:
t=# create sequence so49;
CREATE SEQUENCE
t=# begin;
BEGIN
t=# select nextval('so49');
nextval
---------
1
(1 row)
t=# set transaction_read_only TO on;
SET
t=# select nextval('so49');
ERROR: cannot execute nextval() in a read-only transaction
t=# end;
ROLLBACK
I presume you connected as so called ro user, which is user with "transaction_read_only" set to true, EG:
t=# select rolconfig from pg_roles where rolname ='ro';
rolconfig
----------------------------
{transaction_read_only=on}
(1 row)
you can switch that off for your user of course, but this is out of scope I believe
https://www.postgresql.org/docs/current/static/sql-set-transaction.html

Using DDL command Create User with iBatis for Oracle

I was trying to execute the DDL command for Oracle database, using iBatis.
I want to execute below query using iBatis, how should I execute. I am using struts 1.2 for coding.
CREATE USER USER1..;
I have tried using the element of iBatis, but its doesn't work.
Please anyone provide me quick solution for the same.
DDL is not officially supported in iBatis, but still many times it is executed successfully with iBatis.
I have taken a simple DDL command for creating user, which runs correctly in Oracle.
CREATE USER MYUSER IDENTIFIED BY PASSWORD;
Then used mapped statement in iBatis. The <statement> mapped statement can hold any SQL statement. I referred Mapped Statements for iBatis from this link.
Then I have created statement for iBatis with create user DDL and passed a parameter class as UserToCreate.
<statement id="createUser" parameterClass="UserToCreate">
CREATE USER #userName# IDENTIFIED BY PASSWORD
</statement>
The UserToCreate.java file is a bean holding data related to user to be created.
public class UserToCreate{
private String userName;
// Any other field variable
//Getter Setter methods
}
Now for calling the Create User iBatis statement just write use code:
UserToCreate user = new UserToCreate();
user.setName("MYUSER");
// sqlMap is an object of ibatis SqlMapClient
sqlMap.update("createUser", user);
This will create a new Oracle User, as specified by the user name in variable userName.

Configure Oracle name resolution for procedures

I've got a procedure
shema_name.package_name.procedure_name
The software using database is written to call it like:
call package_name.procedure_name;
How do I configure the login software uses to access the database so that name resolution is performed correctly? Note that the login accessing database and the procedure definer are different.
You have 2 options:
Create a synonym:
create synonym package_name for schema_name.package_name
use current_schema session parameter:
ALTER SESSION set current_schema = schema_name
Make public synonyms to all objects referenced like this.
Or, if only one schema refers to them and you don't want to pollute public namespace - make synonyms only in that schema.

how do i get the current schema on DB2 if i have a JDBC conneciton?

If I have an instance of a JDBC DB2 connection, how do I get the current schema?
Either a SQL statement would work, or just a JDBC method call.
select current_schema
from sysibm.sysdummy1
;

Change Oracle JDBC Thin Client Identifier

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.

Resources