Qt中Oracle数据库的DateTime类型
Oracle数据库的DateTime字段无法直接用字符串插入,必须用to_data函数强制转换。还好,Qt提供一种简便的方法。
Qt文档中《Data Types for Qt-supported Database Systems》这篇文章给出不同数据库中推荐使用的数据类型。
其中Oracle数据类型表格如下:
Oracle Call Interface Data Types
<th>
SQL type description
</th>
<th>
Recommended input (C++ or Qt data type)
</th>
<td>
FLOAT, DOUBLE, PRECISIONc REAL
</td>
<td>
By default mapping to <a href="qstring.html">QString</a>
</td>
<td>
INTEGER INT SMALLINT
</td>
<td>
typedef qint8/16/32/64
</td>
<td>
NUMERIC(p,s) DECIMAL(p,s)a
</td>
<td>
By default mapping to <a href="qstring.html">QString</a>
</td>
<td>
Character string (NATIONAL CHARACTER VARYING(n) NATIONAL CHAR VARYING(n) NCHAR VARYING(n))
</td>
<td>
Mapped to <a href="qstring.html">QString</a>
</td>
<td>
Character string (NATIONAL CHARACTER(n) NATIONAL CHAR(n) NCHAR(n))
</td>
<td>
Mapped to <a href="qstring.html">QString</a>
</td>
<td>
Character string (CHARACTER(n) CHAR(n))
</td>
<td>
Mapped to <a href="qstring.html">QString</a>
</td>
<td>
Character large string object
</td>
<td>
Mapped to <a href="qstring.html">QString</a>
</td>
<td>
A binary large object
</td>
<td>
Mapped to <a href="qbytearray.html">QByteArray</a>
</td>
<td>
Year, month, and day values of date, as well as hour, minute, and second values of time
</td>
<td>
Mapped to <a href="qdatetime.html">QDateTime</a>
</td>
- DateTime类型与TIMESTAMP类型相似,可以用QDateTime来表示。也就是当数据类型为QDateTime时,qt在QSqlQuery::bindValue时自动将其转换成Oracle的日期时间类型,而无需我们手动调用to_date函数。Qt的Oracle数据库插件qsql_oci实现上述功能。
- 函数
- [cpp]
- int QOCIResultPrivate::bindValue(OCIStmt *sql, OCIBind **hbnd, OCIError *err, int pos,
- const QVariant &val, dvoid *indPtr, ub2 *tmpSize, QList &tmpStorage)
- [/cpp]
- 用于绑定数据。对不同类型的val数据,进行不同的处理。
- 例如
- [cpp]
- switch (val.type()) {
- case QVariant::ByteArray:
- r = OCIBindByPos(sql, hbnd, err,
- pos + 1,
- isOutValue(pos)
- ? const_cast(reinterpret_cast(data)->constData())
- reinterpret_cast(data)->data(),
reinterpret_cast(data)->size(),
SQLT_BIN, indPtr, 0, 0, 0, 0, OCI_DEFAULT);
break;
case QVariant::Int:
r = OCIBindByPos(sql, hbnd, err,
pos + 1,
// if it’s an out value, the data is already detached
// so the const cast is safe.
const_cast(data),
sizeof(int),
SQLT_INT, indPtr, 0, 0, 0, 0, OCI_DEFAULT);
break;
[/cpp]
对于DateTime类型,有如下的处理:
[cpp]
case QVariant::Time:
case QVariant::Date:
case QVariant::DateTime: {
QByteArray ba = qMakeOraDate(val.toDateTime());
r = OCIBindByPos(sql, hbnd, err,
pos + 1,
ba.data(),
ba.size(),
SQLT_DAT, indPtr, 0, 0, 0, 0, OCI_DEFAULT);
tmpStorage.append(ba);
break; }
[/cpp]
调用qMakeOraDate()函数生成Oracle可以识别的日期。函数实现如下:
[cpp]
QByteArray qMakeOraDate(const QDateTime& dt)
{
QByteArray ba;
ba.resize(7);
int year = dt.date().year();
ba[0]= (year / 100) + 100; // century
ba[1]= (year % 100) + 100; // year
ba[2]= dt.date().month();
ba[3]= dt.date().day();
ba[4]= dt.time().hour() + 1;
ba[5]= dt.time().minute() + 1;
ba[6]= dt.time().second() + 1;
return ba;
}
[/cpp]
另外还有从Oracle日期转换到QDateTime的函数。
[cpp]
QDateTime qMakeDate(const char* oraDate)
{
int century = oraDate[0];
if(century >= 100){
int year = uchar(oraDate[1]);
year = ((century-100)*100) + (year-100);
int month = oraDate[2];
int day = oraDate[3];
int hour = oraDate[4] – 1;
int min = oraDate[5] – 1;
int sec = oraDate[6] – 1;
return QDateTime(QDate(year,month,day), QTime(hour,min,sec));
}
return QDateTime();
}
[/cpp]
所以,还是使用QDateTime代表时间较为方便。