MSSQL For Real Man

When I started adding the support of a new FB4 datatype TIMESTAMP WITH TIME ZONE, I did a small test with MSSQL 2008, where this datatype is presented as datetimeoffset:

create table TBL__TS_WITH_TZ
(
 COL_TS_WITH_TZ datetimeoffset(4)
);

insert into TBL__TS_WITH_TZ (COL_TS_WITH_TZ) VALUES ('2023-04-27 11:18:00.0000 +03:30')
insert into TBL__TS_WITH_TZ (COL_TS_WITH_TZ) VALUES ('2023-04-27 11:19+04:30')
insert into TBL__TS_WITH_TZ (COL_TS_WITH_TZ) VALUES ('2023-06-21 13:19:57+04:37')

It was a couple months ago.

Today it was needed to read these records through MSSQL OLE DB provider (MSOLEDBSQL) to check this data. Provider returns datetimeoffset in DBTIMESTAMPOFFSET structure.

Ok, I was thought and wrote the following utility on C++:

#include <_pch_.h>
#pragma hdrstop

#include <ole_lib/oledb/oledb_client_lib.h>
#include <ole_lib/com_initialize.h>
#include <iostream>

////////////////////////////////////////////////////////////////////////////////
using namespace std;
////////////////////////////////////////////////////////////////////////////////

void Execute()
{
 cout<<"GO!"<<endl;

 const ole_lib::TComInitialize2 __co_init(COINIT_MULTITHREADED);

 oledb_lib::t_db_data_source ds;

 const oledb_lib::t_oledb_char* const c_cn_str
  =_OLEDB_LIB_T
    ("Provider=MSOLEDBSQL;Data Source=VW7X64\\SQLEXPRESS, 49253;Initial Catalog=test;")

   _OLEDB_LIB_T
    ("User ID=sa;Password=mssql;Prompt=4;");

 cout<<"Connect to database ..."<<endl;

 _THROW_OLEDB_FAILED(ds,initialize(c_cn_str))

 oledb_lib::t_db_session session;

_THROW_OLEDB_FAILED(session,create(ds))

 cout<<"Start transaction ..."<<endl;

_THROW_OLEDB_FAILED(session,start_transaction());

 //---------------------------
 oledb_lib::t_db_command cmd;

 _THROW_OLEDB_FAILED(cmd,create(session))

 //---------------------------
 oledb_lib::t_db_row row;

 const oledb_lib::t_oledb_char* const c_sql
  =_OLEDB_LIB_T("select COL_TS_WITH_TZ from TBL__TS_WITH_TZ");

 cout<<"Prepare ["<<structure::tstr_to_str(c_sql)<<"] ..."<<endl;

 _THROW_OLEDB_FAILED(cmd,prepare_ex(c_sql,&row,0));

 //---------------------------
 cout<<"Execute ..."<<endl;

 _THROW_OLEDB_FAILED(cmd,execute(nullptr));

 //---------------------------
 _THROW_OLEDB_FAILED(cmd,bind(row));

 while(cmd.fetch(row)==S_OK)
 {
  cout<<"FIELD: "<<print(row[0])<<endl;
 }//while

 _THROW_OLEDB_FAILED(cmd,m_last_result)

 //---------------------------
 cout<<"Commit ..."<<endl;

_THROW_OLEDB_FAILED(session,commit());
}//Execute

////////////////////////////////////////////////////////////////////////////////

int main()
{
 try
 {
  Execute();
 }
 catch(const std::exception& e)
 {
  cout<<"ERROR: "<<e.what()<<endl;
 }//catch
 
 return 0;
}//main

////////////////////////////////////////////////////////////////////////////////

After I had gotten all the necessary information from this test, I thought — it would be stupid to do not share this code 🙂

Leave a Comment