how to do batch insert into table having "timestamp" column using c++ ODBC code
I am writing a c++ code in linux using ODBC , I have a table which is having GEN_TIME column of timestamp type, i need 8 data to insert at a time, i defined
array of SQL_TIMESTAMP_STRUCT lDateAndTime[10]; and filled with data like below
const int NUM_ENTRIES = 8;
lDateAndTime[0].year = 2023;
lDateAndTime[0].month = 8;
lDateAndTime[0].day = 10;
lDateAndTime[0].hour = 11;
lDateAndTime[0].minute = 30;
lDateAndTime[0].second = 0;
lDateAndTime[1].year = 2023;
lDateAndTime[1].month = 8;
lDateAndTime[1].day = 10;
lDateAndTime[1].hour = 11;
lDateAndTime[1].minute = 30;
lDateAndTime[1].second = 0;
And i set insert query like below
ret = SQLPrepare (hdlStmt, (SQLTCHAR*)"INSERT INTO test_evr_details (evr_event, evr_reason, evr_cause, TRANS_ID, GEN_TIME) VALUES (?, ?, ?, ?, ?)" , SQL_NTS) ;
and set the date filed like
ret = SQLBindParameter(hdlStmt, 5, SQL_PARAM_INPUT, SQL_C_TIMESTAMP, SQL_TYPE_TIMESTAMP, 0, 0, (SQLPOINTER)lDateAndTime, sizeof(SQL_TIMESTAMP_STRUCT) , NULL);
and i set the number of batch as
ret = SQLSetStmtAttr( hdlStmt, SQL_ATTR_PARAMSET_SIZE,
(SQLPOINTER)NUM_ENTRIES, 0 );
and executed query as
ret = SQLExecute(hdlStmt);
But it is getting error, if i remove GEN_TIME from the query, then it is inserting 8 rows.
Best Answer
-
SruthiA Administrator
@zachariam : I got it working. I had to do couple of changes. Please find the attached code.
[dbadmin@node3 ~]$ g++ -o test10 test1.cpp -lodbc
[dbadmin@node3 ~]$ ./test10
Allocated an environment handle.
Set application to ODBC 3.
Allocated Database handle.
Connecting to database.
Connected to database.
Disabling autocommit.
Creating prepared statement
Created prepared statement.
Bound EvrEvent array to prepared statement
Bound DateAndTime array to prepared statement
Set numbers of rows
successful.
Row 1 inserted successsfully
Row 2 inserted successsfully
Row 3 inserted successsfully
Committing transaction
Committed transaction
Free handles.
[dbadmin@node3 ~]$ vsql
Welcome to vsql, the Vertica Analytic Database interactive terminal.Type: \h or \? for help with vsql commands
\g or terminate with semicolon to execute query
\q to quitBad terminal type: "xterm". Will assume vt100.
test=> select * from test_table;
evr_event | gen_time
-----------+---------------------
1 | 2023-08-10 11:30:11
2 | 2023-08-10 11:30:01
3 | 2023-08-10 11:30:01
(3 rows)test=>
0
Answers
I am also looking for the same. Can someone please help on this?
I'll need more info to figure this out. Can you post the complete example? What was the exact error message?
i create a test table like below
TSSDB=> \d test_table
List of Fields by Tables
Schema | Table | Column | Type | Size | Default | Not Null | Primary Key | Foreign Key
--------+------------+-----------+-----------+------+---------+----------+-------------+-------------
RPPRS | TEST_TABLE | EVR_EVENT | int | 8 | | f | f |
RPPRS | TEST_TABLE | GEN_TIME | timestamp | 8 | | f | f |
(2 rows)
I Create a test code like below to insert 3 rows to this test table
include <stdio.h>
include <stdlib.h>
include <time.h>
include <unistd.h>
include <sql.h>
include <sqltypes.h>
include <sqlext.h>
include <string.h>
int main()
{
// Number of data rows to insert
const int NUM_ENTRIES = 3;
}
I compiled the code like
g++ -o TEST_BatchInsert TestBatchInsert.cc -lodbc
I run the executable like below
[prs@v110 VerticaTestCode]$ ./TEST_BatchInsert
Allocated an environment handle.
Set application to ODBC 3.
Allocated Database handle.
Connecting to database.
Connected to database.
Disabling autocommit.
Creating prepared statement
Created prepared statement.
Bound EvrEvent array to prepared statement
Bound DateAndTime array to prepared statement
Set numbers of rows
not successful!
Committing transaction
Committed transaction
Free handles.
Table content after execute
TSSDB=> select * from test_table;
EVR_EVENT | GEN_TIME
-----------+---------------------
1 | 2023-08-10 11:30:00
(1 row)
Problem
It is inserting only 1 time, i coded it to insert 3 times. if i remove the code for GEN_TIME and put only EVR_EVENT in query, then it is working fine and inserting 3 rows.
I was able to compile your code on my test cluster, and it runs successfully inserting 3 rows with ODBC driver v23.3.0. I will see if this was a known issue, but please obtain the latest driver from https://www.vertica.com/download/vertica/client-drivers/
ODBC driver is backwards compatible to Vertica 8 so the latest client should still work with your server.
@zachariam : I am able to reproduce the issue locally
[dbadmin@node3 ~]$ g++ -o test9 test.cpp -lodbc
[dbadmin@node3 ~]$ ./test9
Allocated an environment handle.
Set application to ODBC 3.
Allocated Database handle.
Connecting to database.
Connected to database.
Disabling autocommit.
Creating prepared statement
Created prepared statement.
Bound EvrEvent array to prepared statement
Bound DateAndTime array to prepared statement
Set numbers of rows
not successful!
Committing transaction
Committed transaction
Free handles.
[dbadmin@node3 ~]$ vsql
Welcome to vsql, the Vertica Analytic Database interactive terminal.
Type: \h or \? for help with vsql commands
\g or terminate with semicolon to execute query
\q to quit
Bad terminal type: "xterm". Will assume vt100.
test=> select * from test_table;
evr_event | gen_time
-----------+---------------------
1 | 2023-08-10 11:30:00
(1 row)
test=> select version();
version
Vertica Analytic Database v23.3.0-1
(1 row)
I added more debugging with a helper function and found that insertion is failing because of datetime overflow.
[dbadmin@node3 ~]$ g++ -o test10 test1.cpp -lodbc
[dbadmin@node3 ~]$ ./test10
Allocated an environment handle.
Set application to ODBC 3.
Allocated Database handle.
Connecting to database.
Connected to database.
Disabling autocommit.
Creating prepared statement
Created prepared statement.
Bound EvrEvent array to prepared statement
Bound DateAndTime array to prepared statement
Set numbers of rows
error record 1
sqlstate: 22008
detailed msg: [Vertica][Support] (40520) Datetime field overflow resulting from invalid datetime.
native error code: 40520
not successful!
Committing transaction
Committed transaction
Free handles.
[dbadmin@node3 ~]
I updated vertica driver to 23.3, but still i am getting error . i compiled code using /usr/lib/libodbc.so -> libodbc.so.2.0.0 , and i run the executable in another server having vertica driver/client 23.3, where is the issue i am not getting.
[prs@v112 ~]$ rpm -qa | grep vertica-client
vertica-client-23.3.0-0.x86_64
[prs@v112 ~]$
[prs@v112 ~]$
[prs@v112 ~]$ ./TEST_BatchInsert
Allocated an environment handle.
Set application to ODBC 3.
Allocated Database handle.
Connecting to database.
Connected to database.
Disabling autocommit.
Creating prepared statement
Created prepared statement.
Bound EvrEvent array to prepared statement
Bound DateAndTime array to prepared statement
Set numbers of rows
not successful!
Committing transaction
Committed transaction
Free handles.
How to solve this issue, how to set the dates properly, can you help. how you are able to print some debugging information, can you tell how to enable it, my executable just says not successful.
[prs@v112 ~]$ rpm -qa | grep vertica-client
vertica-client-23.3.0-0.x86_64
[prs@v112 ~]$
[prs@v112 ~]$
[prs@v112 ~]$ ./TEST_BatchInsert
Allocated an environment handle.
Set application to ODBC 3.
Allocated Database handle.
Connecting to database.
Connected to database.
Disabling autocommit.
Creating prepared statement
Created prepared statement.
Bound EvrEvent array to prepared statement
Bound DateAndTime array to prepared statement
Set numbers of rows
not successful!
Committing transaction
Committed transaction
Free handles.
@SruthiA , Thanks , it worked .
I followed Vertica documentation page, can you edit/add example having DATETIME batch insert also, current example is having only integer and text field batch insert. since most of the tables having datetime column so it will help many vertica c++ application developers. based on below example only i tried but in that datetime example not available
https://www.vertica.com/docs/10.0.x/HTML/Content/Authoring/ConnectingToVertica/ClientODBC/UsingBatchInserts.htm
actual issue with the code was some junk value was going as input , i added memset and now my code is working without this modifications. i added below code before filling date and time to the structure. Thanks for your help
memset(&lDateAndTime, 0, sizeof(lDateAndTime));
@zachariam : Good to know it worked and thanks for sharing your feedback. I have raised a documentation JIRA .