Wednesday, October 28, 2015

How to work around ORA-29275: partial multibyte character when using chr function

If you need to check what is actually stored in a database table, meaning the internal representation, you can use the DUMP function.

It will return a varcar2 value containing the data type code, length in bytes, and internal representation

SQL> select dump ('ø',1010) from dual;

DUMP('Ø',1010)
--------------------------------------------------------------------------------
Typ=96 Len=2 CharacterSet=AL32UTF8: 195,184

So the type above is 96, representing a VARCHAR2 or NVARCHAR datatype, the length is 2 bytes, the characterset of the database is AL32UTF8 and the decimal values of each byte is 195 and 184.

For single-byte character set, it would be easy to check which character the decimal represented under the database's characterset; simply use the chr function and pass the decimal value as an argument.

However with a multibyte character set, which one of the returned decimal functions should you choose?
SQL> select chr(195) from dual;

ERROR:
ORA-29275: partial multibyte character

A workaround is to dump the character to hexadecimal format instead of decimal, by using the argument 1016 as the second argument to the function:
SQL>  select dump ('ø',1016) from dual;

DUMP('Ø',1016)
--------------------------------------------------------------------------------
Typ=96 Len=2 CharacterSet=AL32UTF8: c3,b8

The c3b8 hexadecimal value corresponds to the decimal value of 50104. Pass this value to the chr function and you get the result you're looking for:

SQL> select chr(50104) from dual;

CHR(50
------
ø

A brilliant converter between decimal and hexadecimal numbers can be found here

The documentation for the dump function can be found at http://docs.oracle.com/cd/E11882_01/server.112/e41084/functions055.htm#SQLRF00635

The documentation for the chr function can be found at http://docs.oracle.com/cd/E11882_01/server.112/e41084/functions026.htm#SQLRF00616

The datatype table is listed here: https://docs.oracle.com/cd/B19306_01/appdev.102/b14250/oci03typ.htm#i422575

Monday, October 5, 2015

Is it possible to change the character set of the database by recreating the control file?

Question: Is it possible to change the character set of the database by recreating the controlfil?
Answer: No, this is not supported.

Doc ID 225912.1 states:

"Note also that it's NOT possible to change / adapt the NLS_CHARACTERSET by re-creating the control file.
The characterset specified in CREATE CONTROLFILE DATABASE ... RESETLOGS ....CHARACTER SET ; ( the result of an ALTER DATABASE BACKUP CONTROLFILE TO TRACE..) need to be the actual current NLS_CHARACTERSET of the database."


Question: So why does CREATE CONTROLFILE generate a CHARACTERSET clause in the first place then?
Answer: In case media recovery is required after the controlfile has been recreated.

From the documentation:
"If you specify a character set, then Oracle Database reconstructs character set information in the control file. If media recovery of the database is subsequently required, then this information will be available before the database is open, so that tablespace names can be correctly interpreted during recovery."

The documentation goes on to say

"This clause is required only if you are using a character set other than the default, which depends on your operating system."

Without having found any sources on the internet to confirm my interpretation, I will claim that this means:

* If you recreate your controlfile for a database with, say, WE8ISO8859P1 as character set, you will indeed need to specify the character in the CREATE CONTROLFILE clause.

* If you recreate the controlfile of a database using UTF8, for example AL32UT8, you can skip this clause altogether if you wish

How to pause an Oracle database

Sometimes it is useful to pause a database, and let it finish the running jobs at a later time.
Particularly in environments with shared resources contention may occur. Important databases need to be prioritized while less important ones should be suspended.

For this purpose, you can use the "suspend" command:
alter system suspend;

Alert log:
Mon Oct 05 10:14:49 2015
Suspending database after alter system suspend command

The database_status field in v$instance will reflect the new state of the database:

SQL> select database_status from v$instance;

 DATABASE_STATUS
-----------------

SUSPENDED

When you are ready to resume database activity, issue the following command:

alter system resume;

More info: Oracle Documentation

Tuesday, September 8, 2015

Wednesday, September 2, 2015

How to unzip multiple files on a Unix-based operating systems

When extracting multiple zip files, remember to use single quotes to mask the zip-files:
unzip '*.zip'

For example, when unpacking the files needed to install Oracle 11.2.0.4:
[oracle@lx01 Downloads]$ ls -latr
total 5586768
-rwxr-x---.  1 root   root     1395582860 Sep  2 10:14 p13390677_112040_Linux-x86-64_1of7.zip
-rwxr-x---.  1 root   root     1151304589 Sep  2 10:14 p13390677_112040_Linux-x86-64_2of7.zip
-rwxr-x---.  1 root   root     1205251894 Sep  2 10:15 p13390677_112040_Linux-x86-64_3of7.zip
-rwxr-x---.  1 root   root      656026876 Sep  2 10:16 p13390677_112040_Linux-x86-64_4of7.zip
-rwxr-x---.  1 root   root      599170344 Sep  2 10:16 p13390677_112040_Linux-x86-64_5of7.zip
-rwxr-x---.  1 root   root      488372844 Sep  2 10:16 p13390677_112040_Linux-x86-64_6of7.zip
-rwxr-x---.  1 root   root      119521122 Sep  2 10:16 p13390677_112040_Linux-x86-64_7of7.zip
drwx------. 17 oracle oinstall       4096 Sep  2 10:27 ..
drwxr-xr-x.  2 oracle oinstall       4096 Sep  2 10:34 .
[oracle@lx01 Downloads]$ unzip 'p13390677_112040_Linux-x86-64_*.zip'

Without the quotes, unzip will look for "zip files within zip files".

Thanks to Chris Jean for the tip!

Oracle 11g out-of-place vs. in-place database upgrades

Starting with Oracle 11gR2, Oracle changed their patching strategy.

Previously, a patch set was supposed to be downloaded and installed into an existing ORACLE_HOME.
After 11.2, a "patch set" is really a full release, bundled in a number of zip files.

The default patching method is the "out-out-place", which means that every time customers need to upgrade to a new patch set (say, 11.2.0.4), a new ORACLE_HOME should be created, and the new binaries should be installed here.

So you will potentially end up with a number of ORACLE_HOME on your server, and you can choose to run your database out of either of these, upgrading whenever you please.

See Mike Dietrich's post about the same topic for more details.

How to fix error thrown by OPatch: java.lang.NullPointerException

Problem:

Opatch throws the following error when you are querying the inventory:

[oracle@lx01 ~]$ opatch lsinventory
Oracle Interim Patch Installer version 11.2.0.3.11
Copyright (c) 2015, Oracle Corporation.  All rights reserved.


Oracle Home       : /u01/oracle/product/11.2.0/dbhome_1
Central Inventory : /u01/oraInventory
   from           : /u01/oracle/product/11.2.0/dbhome_1/oraInst.loc
OPatch version    : 11.2.0.3.11
OUI version       : 11.2.0.1.0
Log file location : /u01/oracle/product/11.2.0/dbhome_1/cfgtoollogs/opatch/opatch2015-09-02_08-52-28AM_1.log

Lsinventory Output file location : /u01/oracle/product/11.2.0/dbhome_1/cfgtoollogs/opatch/lsinv/lsinventory2015-09-02_08-52-28AM.txt

--------------------------------------------------------------------------------
java.lang.NullPointerException
 at oracle.sysman.oii.oiin.OiinNetOps.addNICInfo(OiinNetOps.java:144)
 at oracle.sysman.oii.oiin.OiinNetOps.computeNICList(OiinNetOps.java:109)
 at oracle.sysman.oii.oiin.OiinNetOps.(OiinNetOps.java:76)
 at oracle.sysman.oii.oiin.OiinNetOps.getNetOps(OiinNetOps.java:90)
 at oracle.sysman.oii.oiix.OiixNetOps.getFullHostName(OiixNetOps.java:49)
 at oracle.opatch.LsInventoryPrinter.printLocalMachineInfo(LsInventoryPrinter.java:2336)
 at oracle.opatch.LsInventorySession.loadAndPrintInventory(LsInventorySession.java:480)
 at oracle.opatch.LsInventorySession.process(LsInventorySession.java:317)
 at oracle.opatch.OPatchSession.main(OPatchSession.java:2120)
 at oracle.opatch.OPatch.main(OPatch.java:626)
Local Machine Information::
Hostname: lx01.oric.no
ARU platform id: 226
ARU platform description:: Linux x86-64

Installed Top-level Products (1): 

Oracle Database 11g                                                  11.2.0.1.0
There are 1 products installed in this Oracle Home.


There are no Interim patches installed in this Oracle Home.


--------------------------------------------------------------------------------

OPatch succeeded.

Cause:
In my case, the file /etc/hosts was incorrectly configured.

Solution:
Configure the file /etc/hosts correctly.

[root@lx01 ~]# ifconfig 
enp0s3: flags=4163  mtu 1500
        inet 192.168.0.55  netmask 255.255.255.0  broadcast 192.168.0.255

Check the /etc/hosts:

[root@lx01 ~]# cat /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.1.55 lx01.oric.no lx01
[oracle@lx01 ~]$ vi /etc/hosts

Update the incorrect ip address from 192.168.1.55 to 192.168.0.55, and save the file.

Opatch will now display expected output:

[oracle@lx01 ~]$ opatch lsinventory
Oracle Interim Patch Installer version 11.2.0.3.11
Copyright (c) 2015, Oracle Corporation.  All rights reserved.


Oracle Home       : /u01/oracle/product/11.2.0/dbhome_1
Central Inventory : /u01/oraInventory
   from           : /u01/oracle/product/11.2.0/dbhome_1/oraInst.loc
OPatch version    : 11.2.0.3.11
OUI version       : 11.2.0.1.0
Log file location : /u01/oracle/product/11.2.0/dbhome_1/cfgtoollogs/opatch/opatch2015-09-02_09-07-43AM_1.log

Lsinventory Output file location : /u01/oracle/product/11.2.0/dbhome_1/cfgtoollogs/opatch/lsinv/lsinventory2015-09-02_09-07-43AM.txt

--------------------------------------------------------------------------------
Local Machine Information::
Hostname: lx01.oric.no
ARU platform id: 226
ARU platform description:: Linux x86-64

Installed Top-level Products (1): 

Oracle Database 11g                                                  11.2.0.1.0
There are 1 products installed in this Oracle Home.


There are no Interim patches installed in this Oracle Home.


--------------------------------------------------------------------------------

OPatch succeeded.