summaryrefslogtreecommitdiff
path: root/src/sql/drivers
diff options
context:
space:
mode:
authorCharles Yin <charles.yin@nokia.com>2010-07-16 11:15:06 +1000
committerCharles Yin <charles.yin@nokia.com>2010-07-21 10:41:23 +1000
commitf8f255553f3640355d3e196e100778256741701c (patch)
tree93e79ad74f10a71cf974b054f1a8aedc3f233e46 /src/sql/drivers
parentea6e156370c962eecc19c0c406a2d52e28f5682b (diff)
downloadqt4-tools-f8f255553f3640355d3e196e100778256741701c.tar.gz
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
Diffstat (limited to 'src/sql/drivers')
-rw-r--r--src/sql/drivers/oci/qsql_oci.cpp34
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 c56b9955b5..e11cf75f23 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,