diff options
author | Charles Yin <charles.yin@nokia.com> | 2010-07-16 01:15:06 (GMT) |
---|---|---|
committer | Toby Tomkins <toby.tomkins@nokia.com> | 2010-07-22 02:48:54 (GMT) |
commit | 39972703212b5580c9f4fbd2c6ce698f52d35ca0 (patch) | |
tree | 7e18159e7931407da8a53a559d125a0d107af310 | |
parent | 609435eddf02a9321c25f385b91852a47d9152f9 (diff) | |
download | Qt-39972703212b5580c9f4fbd2c6ce698f52d35ca0.zip Qt-39972703212b5580c9f4fbd2c6ce698f52d35ca0.tar.gz Qt-39972703212b5580c9f4fbd2c6ce698f52d35ca0.tar.bz2 |
Fixes the Oracle nchar bug when NLS_CHARSET is different with NLS_NCHAR_CHARSET.
If Oracle national char types use different charset(NLS_NCHAR_CHARSET) with
the database charset (NLS_CHARSET), the oci client need to set OCI_ATTR_CHARSET_FORM
to SQLCS_NCHAR instead of SQLCS_IMPLICIT.
Task-number: QTBUG-10919
Reviewed-by: Michael Goddard
(cherry picked from commit f8f255553f3640355d3e196e100778256741701c)
-rw-r--r-- | src/sql/drivers/oci/qsql_oci.cpp | 34 |
1 files changed, 33 insertions, 1 deletions
diff --git a/src/sql/drivers/oci/qsql_oci.cpp b/src/sql/drivers/oci/qsql_oci.cpp index c56b995..e11cf75 100644 --- a/src/sql/drivers/oci/qsql_oci.cpp +++ b/src/sql/drivers/oci/qsql_oci.cpp @@ -93,8 +93,17 @@ enum { QOCIEncoding = 2002 }; // AL16UTF16LE enum { QOCIEncoding = 2000 }; // AL16UTF16 #endif -static const ub1 CSID_NCHAR = SQLCS_NCHAR; +// Always set the OCI_ATTR_CHARSET_FORM to SQLCS_NCHAR is safe +// because Oracle server will deal with the implicit Conversion +// Between CHAR and NCHAR. +// see: http://download.oracle.com/docs/cd/A91202_01/901_doc/appdev.901/a89857/oci05bnd.htm#422705 +static const ub1 qOraCharsetForm = SQLCS_NCHAR; + +#if defined (OCI_UTF16ID) +static const ub2 qOraCharset = OCI_UTF16ID; +#else static const ub2 qOraCharset = OCI_UCS2ID; +#endif typedef QVarLengthArray<sb2, 32> IndicatorArray; typedef QVarLengthArray<ub2, 32> SizeArray; @@ -209,12 +218,24 @@ void QOCIResultPrivate::setCharset(OCIBind* hbnd) OCI_HTYPE_BIND, // this const cast is safe since OCI doesn't touch // the charset. + const_cast<void *>(static_cast<const void *>(&qOraCharsetForm)), + 0, + OCI_ATTR_CHARSET_FORM, + err); + if (r != 0) + qOraWarning("QOCIResultPrivate::setCharset: Couldn't set OCI_ATTR_CHARSET_FORM: ", err); + + r = OCIAttrSet(hbnd, + OCI_HTYPE_BIND, + // this const cast is safe since OCI doesn't touch + // the charset. const_cast<void *>(static_cast<const void *>(&qOraCharset)), 0, OCI_ATTR_CHARSET_ID, err); if (r != 0) qOraWarning("QOCIResultPrivate::setCharset: Couldn't set OCI_ATTR_CHARSET_ID: ", err); + } int QOCIResultPrivate::bindValue(OCIStmt *sql, OCIBind **hbnd, OCIError *err, int pos, @@ -939,6 +960,17 @@ void QOCICols::setCharset(OCIDefine* dfn) OCI_HTYPE_DEFINE, // this const cast is safe since OCI doesn't touch // the charset. + const_cast<void *>(static_cast<const void *>(&qOraCharsetForm)), + 0, + OCI_ATTR_CHARSET_FORM, + d->err); + if (r != 0) + qOraWarning("QOCIResultPrivate::setCharset: Couldn't set OCI_ATTR_CHARSET_FORM: ", d->err); + + r = OCIAttrSet(dfn, + OCI_HTYPE_DEFINE, + // this const cast is safe since OCI doesn't touch + // the charset. const_cast<void *>(static_cast<const void *>(&qOraCharset)), 0, OCI_ATTR_CHARSET_ID, |