I am trying to set NLS_COMP and NLS_SORT for the current session to check if it will make a difference with regards to some SQL query I am running that is case sensitive, for some reason the parameters will not change
what am I doing wrong?
SELECT * FROM nls_database_parameters where parameter in ('NLS_COMP','NLS_SORT');
>>> NLS_SORT BINARY
>>> NLS_COMP BINARY
SELECT * FROM nls_instance_parameters where parameter in ('NLS_COMP','NLS_SORT');
>>> NLS_SORT NULL
>>> NLS_COMP BINARY
ALTER SESSION SET NLS_COMP=LINGUISTIC;
>>>session SET altered.
ALTER SESSION SET NLS_SORT=BINARY_CI;
>>>session SET altered.
SELECT * FROM nls_database_parameters where parameter in ('NLS_COMP','NLS_SORT');
>>> NLS_SORT BINARY
>>> NLS_COMP BINARY
SELECT * FROM nls_instance_parameters where parameter in ('NLS_COMP','NLS_SORT');
>>> NLS_SORT NULL
>>> NLS_COMP BINARY
You are setting the session values but reading the system ones. Try reading from NLS_SESSION_PARAMETERS:
SELECT *
FROM NLS_SESSION_PARAMETERS
WHERE PARAMETER IN ('NLS_COMP', 'NLS_SORT');
Related
We are trying the following request in Oracle Database 19.3 and the result is ever like the case sensitivity was ignores.
select 1 from dual where regexp_like('CHIEN', '[a-z]+', 'c');
And the result of the request is
1
Even with:
ALTER SESSION SET NLS_COMP=ANSI;
ALTER SESSION SET NLS_SORT=GERMAN_AI;
We are thinking that's come from a NLS parameter but we don't found which one.
We have those parameters:
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
nls_calendar string GREGORIAN
nls_comp string BINARY
nls_currency string €
nls_date_format string DD/MM/RR
nls_date_language string FRENCH
nls_dual_currency string €
nls_iso_currency string FRANCE
nls_language string FRENCH
nls_length_semantics string BYTE
nls_nchar_conv_excp string FALSE
nls_numeric_characters string ,
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
nls_sort string FRENCH
nls_territory string FRANCE
nls_time_format string HH24:MI:SSXFF
nls_timestamp_format string DD/MM/RR HH24:MI:SSXFF
nls_timestamp_tz_format string DD/MM/RR HH24:MI:SSXFF TZR
nls_time_tz_format string HH24:MI:SSXFF TZR
And our NLS_LANG is set to French_France.AL32UTF8
Finally I found the solution.
The problem was with NLS_SORT=FRENCH (or any linguistic sort)
NLS_SORT=FRENCH => AaBbCcDdEeFfGgHhIiJjKkLlMmNn .... Z
And when we are lookup for regular expression [a-z], we include BCDE ... Z
The solution is to set NLS_SORT=BINARY
In my case, I set environment variable NLS_SORT=BINARY. Without that, Oracle take the default NLS_SORT value that correspond to NLS_LANG.
I created the following table with one text column:
create table table1 (
col1 varchar2(20)
);
Then I inserted one Polish letter to it:
insert into table1 values ('ą')
How can I obtain the number of characters in this string? It should be 1, but all functions that I know return other results:
LENGTH(COL1) -> 2,
LENGTHC(COL1) -> 2,
LENGTH2(COL1) -> 2,
LENGTH4(COL1) -> 2,
LENGTHB(COL1) -> 6.
The SELECT * FROM NLS_DATABASE_PARAMETERS; returns:
PARAMETER VALUE
---------------------------------
NLS_RDBMS_VERSION 18.0.0.0.0
NLS_NCHAR_CONV_EXCP FALSE
NLS_LENGTH_SEMANTICS BYTE
NLS_COMP BINARY
NLS_SORT BINARY
NLS_NCHAR_CHARACTERSET AL16UTF16
NLS_CHARACTERSET AL32UTF8
NLS_ISO_CURRENCY AMERICA
NLS_TERRITORY AMERICA
NLS_LANGUAGE AMERICAN
... ...
You can check it on: dbfiddle.uk.
It is most likely a bug with the version of Oracle you are running the query on or an issue with the character being encoded on the web server.
I have almost all of the same NLS parameters on my system except I am on Oracle 19 instead of 18.
Even on livesql.oracle.com it returns the results as you would expect but again, that database is on Oracle 19.
I am trying to insert date value as dd-mon-yy but the database is storing it as dd/mm/yy.
For example: INSERT INTO tablename VALUES (to_date('01-mar-09', 'dd-mon-yy');
The DB stores it as 01/03/09. Why is that? Whay can't I just store it as 01-mar-09?
Please help.
Date is a raw datatype. It doesn't have a format to be saved. It's upto you or the environment/session to decide how to display it.. use NLS_DATE_FORMAT parameter as required... using alter session or use to_char() function
alter session set nls_date_format = 'DD-MON-YY';
select sysdate from dual;
28-OCT-15
alter session set nls_date_format = 'MM/DD/YY';
select sysdate from dual;
10/28/15
The NLS parameters precedence is decided as below, if not set on session level then use instance level, if not set at instance level then use which is present at database level. Below are the views which provide set values at each level
NLS_SESSION_PARAMETERS => session level parameters
NLS_INSTANCE_PARAMETERS => instance level parameters
NLS_DATABASE_PARAMETERS => database level parameters
Oracle doesn't store a date as any format .. it just stores "a date". you are viewing it/displaying it as a different format. Check your nls_date settings.
SQL> select sysdate from dual;
SYSDATE
---------
28-OCT-15
SQL> alter session set nls_date_format='dd-mon-yyyy hh24:mi:ss'
Session altered.
SQL> select sysdate from dual;
SYSDATE
--------------------
28-oct-2015 11:00:56
SQL>
I'm doing a case-insensitive query with
alter session set NLS_COMP=LINGUISTIC;
alter session set NLS_SORT=BINARY_CI;
Is there a way to easily capture the session state prior to altering it so that I can restore the session to its original state?
You can obtain the current values using:
select *
from nls_session_parameters;
before you change your session. To restore it, you just use the saved values.
I am not aware of any statement that resets the session parameters to the default value.
The NLS parameters are exposed through a series of views, starting with NLS_. In your case you need NLS_SESSION_PARAMETERS. There are equivalent views for Instance and Database.
This is neater than using v$parameter, although that view does allow us to tell whether a paarmeter is changed from the default value.
You can get the value of a given session parameter by:
SELECT value
FROM nls_session_parameters
WHERE parameter = 'NLS_SORT'; -- replace NLS_SORT with parameter of your choice
This answer demonstrates other means of doing a case insensitive search.
Using UPPER()/LOWER() functions with a function based index.
Regular expressions: REGEXP_LIKE()
You can see the parameter values initially :
SQL> SHOW PARAMETER NLS_SORT;
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
nls_sort string BINARY
SQL> SHOW PARAMETER NLS_COMP;
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
nls_comp string BINARY
And then set the session parameter accordingly :
SQL> alter session set nls_comp='LINGUISTIC';
Session altered
SQL> alter session set nls_sort='BINARY_CI';
Session altered
In PL/SQL, you can do the following to fetch the parameter value and store it in session variable :
SQL> DECLARE
2 VAR_NLS_SORT VARCHAR2(10);
3 var_nls_comp VARCHAR2(10);
4 BEGIN
5 SELECT VALUE
6 INTO VAR_NLS_SORT
7 FROM NLS_SESSION_PARAMETERS
8 WHERE PARAMETER = 'NLS_SORT';
9 SELECT VALUE
10 INTO VAR_NLS_COMP
11 FROM NLS_SESSION_PARAMETERS
12 WHERE PARAMETER = 'NLS_COMP';
13 DBMS_OUTPUT.PUT_LINE('NLS_SORT = '||VAR_NLS_SORT);
14 DBMS_OUTPUT.PUT_LINE('NLS_COMP = '||VAR_NLS_COMP);
15 END;
16 /
NLS_SORT = BINARY
NLS_COMP = BINARY
PL/SQL procedure successfully completed.
For more information, you can have a look at Oracle – Case Insensitive Sorts & Compares
I tried to run a simple query which shows a weird date output format. When i try to run the below query, I get no value as output.
select value from SYS.nls_database_parameters where parameter = 'NLS_date_format';
please help.
See the difference? Your query first, mine second.
SQL> select value from SYS.nls_database_parameters where parameter = 'NLS_date_format';
no rows selected
SQL> select value from SYS.nls_database_parameters where parameter = 'NLS_DATE_FORMAT';
VALUE
--------------------------------------------------------------------------------
DD-MON-RR
SQL>
Parameters' names are UPPERCASE, e.g.
SQL> select parameter from nls_database_parameters where rownum < 5;
PARAMETER
------------------------------
NLS_LANGUAGE
NLS_TERRITORY
NLS_CURRENCY
NLS_ISO_CURRENCY
SQL>