Feature Requests: Browse | Submit New | Admin

[#29617] Setting NLS_LANG

Date:
2012-07-25 09:55
Priority:
3
Submitted By:
Per Grottum (pergr)
Assigned To:
Nobody (None)
Category:
None
State:
Open
Summary:
Setting NLS_LANG

Detailed description
I am new to this site so I have to apologize if I raise a question that has already been dealt with.

I use ruby-oci for communication with several databases, unfortunately generated with several NLS_LANG settings. Particularly
in Rails/Passenger applications it would be very convenient to be able to set NLS_LANG programatically inside the application
irrespective of the external environment. I have noticed that Oracle provide a function for this in their instantclient
API, and I wonder whether this is or could be implemented in ruby-oci8, see:
http://docs.oracle.com/cd/B28359_01/appdev.111/b28390/globalization.htm#i1000999
Thank you.

Per

Add A Comment: Notepad

Please login


Followup

Message
Date: 2012-12-17 10:27
Sender: Per Grottum

Since there has been no development in this matter, I have 
made a temporary hack to solve the problem.

When ruby-oci8 is loaded the procedure Init_oci8lib() in 
oci8lib.c is called. It in turn calls oci8_make_envhp in 
env.c which sets up the environment. Originally 
oci8_make_envhp employed the Oracle OCI-routine 
OCIEnvCreate to accomplish this. Oracle has another version 
of the same routine, OCIEnvNlsCreate which makes it 
possible to set the equivalent of NLS_LANG and NLS_NCHAR 
for the current application. The problem is how to pass the 
desired parameters to this routine. I have found no way to 
pass a parameter in the call to Init_oci8lib(), so I ended 
up defining a global parameter as the first line in the 
actual Rails-application's config/environment.rb, e.g.:
$my_nls_lang = 'WE8ISO8859P1'
This variable can be picked up and processed in env.c by 
e.g. the following modified code:
OCIEnv *oci8_make_envhp(void)
{
    sword rv;
    VALUE NLSL;
    ub2 nlsid;
    OCIEnv *envhp;

    NLSL = rb_gv_get("my_nls_lang");

    if (TYPE(NLSL) == T_STRING) {
        rv = OCIEnvCreate(&envhp, oci8_env_mode, NULL, 
NULL, NULL, NULL, 0, NULL);
        nlsid = OCINlsCharSetNameToId(envhp, StringValuePtr
(NLSL));
        OCIHandleFree(envhp, OCI_HTYPE_ENV);
    }
    else {
        nlsid = 0;
    }

    rv = OCIEnvNlsCreate(&oci8_global_envhp, oci8_env_mode, 
NULL, NULL, NULL, NULL, 0, NULL, nlsid, nlsid);
    if (rv != OCI_SUCCESS) {
        oci8_raise_init_error();
    }
    return oci8_global_envhp;
}

I have not experimented with different codes for NLS_LANG 
and NLS_NCHAR, but only used the same for both. The default 
0 means that the system NLS_LANG and NLS_NCHAR will be used.

I have tested this in a production of Rails running under 
Apache/Passenger with two Rails-applications using 
different databases and NLS_LANG, and it works.

Per
 

Attached Files:

Name Description Download
No Files Currently Attached

Changes:

No Changes Have Been Made to This Item