0

I want to change the NLS_SORT and NLS_COMP parameters for every query to this particular schema, but there are other users on this system as well that want to keep the original values, so using ALTER SYSTEM SET is a no-no in this case. I also don't want to change every query to this particular schema.

Is there a way to either put these values in an initialization file that is particular to only this schema or can I somehow add a trigger that sets these values on the session whenever a session is started to this schema?

I am running Oracle Express 11G R2 and the solution does not need to be backwards compatible.

My goal is to not have to run the ALTER SESSION SET rows before running the SELECT-LIKE-statement and having it produce two results rather than one. Here is the Java sample code that I've used to examine what values I actually want the NLS_COMP and NLS_SORT values to have:

public class OracleCaseTest {
    public static void main(String[] args) throws SQLException {
        BasicDataSource dataSource = new BasicDataSource();
        dataSource.setDriverClassName("oracle.jdbc.driver.OracleDriver");
        dataSource.setUrl("jdbc:oracle:thin:@localhost:1521:xe");
        dataSource.setUsername("CASETEST");
        dataSource.setPassword("casetest");

        Connection conn = null;
        PreparedStatement createStatement = null;
        PreparedStatement populateStatement = null;
        PreparedStatement comparisonAlterSessionStatement = null;
        PreparedStatement sortAlterSessionStatement = null;
        PreparedStatement queryStatement = null;
        PreparedStatement deleteStatement = null;
        ResultSet rs = null;

        conn = dataSource.getConnection();

        createStatement = conn
                .prepareStatement("CREATE TABLE CollationTestTable ( Name varchar(255) )");
        createStatement.execute();

        try {
//            comparisonAlterSessionStatement = conn
//                    .prepareStatement("ALTER SESSION SET NLS_COMP=LINGUISTIC");
//            comparisonAlterSessionStatement.execute();
//
//            sortAlterSessionStatement = conn.prepareStatement("ALTER SESSION SET NLS_SORT=BINARY_CI");
//            sortAlterSessionStatement.execute();

            String[] names = { "pepe", "pépé", "PEPE", "MEME", "mémé", "meme" };
            for (String name : names) {
                populateStatement = conn
                        .prepareStatement("INSERT INTO CollationTestTable VALUES (?)");
                populateStatement.setString(1, name);
                populateStatement.execute();
            }

            queryStatement = conn
                    .prepareStatement("SELECT Name FROM CollationTestTable WHERE NAME LIKE 'pe%'");
            rs = queryStatement.executeQuery();

            while (rs.next()) {
                System.out.println(rs.getString(1));
            }
        } finally {

            deleteStatement = conn.prepareStatement("DROP TABLE CollationTestTable");
            deleteStatement.execute();
        }
    }
}

I'm aware of the problem with full table scans without linguistic indexes that this might create, but ignore that for this question.

UPDATE: This is the statement I used to create my trigger from the SQL command-line interface (after connecting and logging in with my user):

create or replace trigger nls_settings 
after logon on schema 
begin 
EXECUTE IMMEDIATE 'ALTER SESSION SET NLS_COMP=LINGUISTIC'; 
EXECUTE IMMEDIATE 'ALTER SESSION SET NLS_SORT=BINARY_CI'; 
end nls_settings; 
/ 

Also changed the original question to indicate that by "database", in the Oracle world I really meant "schema"/"user".

Stefan Thyberg
  • 3,445
  • 3
  • 23
  • 29

2 Answers2

3

You can create trigger on

  • database startup or instance shutdown
  • user logon or logoff

http://download.oracle.com/docs/cd/B14117_01/server.101/b10743/triggers.htm#i6061

bpgergo
  • 15,669
  • 5
  • 44
  • 68
  • Tried this and it worked fine as long as I was using a thin connector. Now that we need to switch to a thick connector, oci8, we have a problem with this again but as long as you're using a thin connector I think this is the easiest fix. – Stefan Thyberg Nov 14 '11 at 14:03
  • If this is still a problem for you, then I suggest to ask a new question and make sure you provide SO with the following details: 1) source of the trigger you have (and expect to fire on logon); 2) the exact method you are using for logon with OCI (like http://download.oracle.com/docs/cd/B19306_01/appdev.102/b14250/oci15rel001.htm#sthref2423, and source as well). – bpgergo Nov 14 '11 at 14:20
  • I'm in touch with an Oracle consultant now and we're going the route of modifying our DataSource so that whenever a new connection is fetched, it runs the nls_comp and nls_sort commands first. – Stefan Thyberg Nov 18 '11 at 11:20
1

First off, can you clarify what you mean by "database"? In Oracle terminology, a database is the set of schemas that would be affected by an ALTER SYSTEM call. It is possible to have multiple databases on a single server but you can only have one XE database on a machine. If you are coming from a SQL Server background, what SQL Server calls a "database" is more similar to what Oracle calls a "schema".

Assuming that you really mean schema and not database, and assuming that the Oracle CASETEST user only interacts with tables in the one schema, I would second bpgergo's suggestion of a login trigger in the CASETEST schema.

Justin Cave
  • 227,342
  • 24
  • 367
  • 384
  • Indeed, I've had to update myself on the terminology since Oracle databases use a slightly different meaning for the terms schema and database than other relational databases. I found this SO question to be of great help, for example: http://stackoverflow.com/questions/880230/difference-between-a-user-and-a-schema-in-oracle What I meant was really a schema since I think we will have all our applications tables under one user. I have now updated my question to reflect this. – Stefan Thyberg Nov 08 '11 at 16:06