Default Collation and PL/SQL

One of the new features that got introduced in Oracle Database 12.2 is the possibility to define the default collation at schema-, table- or column-level. This is quite nice because we do not have to use NLS_SORT in each and every query anymore.
But obviously there are some restrictions. Let’s create two users, one with no specific collation and one that uses a non-default collation.

SQL> show user
USER is "SYS"
SQL> show pdbs

    CON_ID CON_NAME                       OPEN MODE  RESTRICTED
---------- ------------------------------ ---------- ----------
         3 PDBMMI                         READ WRITE NO

         
SQL> create user usr_default identified by xxx;

User created.

SQL> grant create session, alter session, create procedure to usr_default;

Grant succeeded.

SQL> create user usr_collate identified by xxx default collation binary;

User created.

SQL> grant create session, alter session, create procedure to usr_collate;

Grant succeeded.

Now I create a simple piece of PL/SQL, first with the default user.

SQL> conn usr_default/xxx@pdbmmi
Connected.
SQL> show user
USER is "USR_DEFAULT"
SQL> select default_collation from user_users;

DEFAULT_COLLATION
--------------------------------------------------------------------------------
USING_NLS_COMP

SQL> create procedure do_nothing
  2  as
  3  begin
  4    null;
  5  end;
  6  /

Procedure created.

SQL> exec do_nothing;

PL/SQL procedure successfully completed.

SQL> drop procedure do_nothing;

Procedure dropped.

Nothing special here. Everything works as expected and as we know it since years. So let’s try the same with the user that has a different default collation.

SQL> conn usr_collate/xxx@pdbmmi
Connected.
SQL> show user
USER is "USR_COLLATE"
SQL> select default_collation from user_users;

DEFAULT_COLLATION
--------------------------------------------------------------------------------
BINARY

SQL> create procedure do_nothing
  2  as
  3  begin
  4    null;
  5  end;
  6  /

Warning: Procedure created with compilation errors.

SQL> show err
Errors for PROCEDURE DO_NOTHING:

LINE/COL ERROR
-------- -----------------------------------------------------------------
0/0      PL/SQL: Compilation unit analysis terminated
0/0      PLS-00761: Program unit collation may only be USING_NLS_COMP

Obviously the PL/SQL compiler is not very happy with the different collation option. So we need to change that, at session level in my case, to make it compile.

SQL> alter session set default_collation=USING_NLS_COMP;

Session altered.

SQL> alter procedure do_nothing compile;

Procedure altered.

SQL> show err
No errors.
SQL> exec do_nothing;

PL/SQL procedure successfully completed.

SQL> drop procedure do_nothing;

Procedure dropped.

Now it compiles without any warnings or errors.

So keep that in mind when you create users with a specific collation option.