Question about POCO ODBC Library

Please post support and help requests here.
boriskao
Posts: 2
Joined: 22 Jan 2014, 14:10

Question about POCO ODBC Library

Postby boriskao » 23 Jan 2014, 05:54

I use POCO 1.5.2, unixODBC 2.3.2 and the lastest Sybase ODBC driver(15.7 sp110).
Could I use the return value of execute function for select statement?

string a,b,c;
Statement select(session);
select << "SELECT A,B,C FROM test",
into(a),
into(b),
into(c),
range(0, 1);

while(!select.done()){
if(select.execute()) {
use variable a,b,c ......
}
}

If table test is empty, the return value of select.execute() will be 18446744073709551615.
Because in POCO/Data/ODBC/ODBCStatementImpl.cpp line 468
if (!Utility::isError(SQLRowCount(_stmt, &rows)))
_affectedRowCount = static_cast<std::size_t>(rows);
Sybase ODBC driver will return -1 if there is no data return for select command(Freetds return 0).
static_cast -1 to size_t will be 18446744073709551615.
In easysoft website, it says SQLRowCount return -1 for select in most ODBC drivers.
http://www.easysoft.com/support/kb/kb00939.html

My second question is about how does POCO ODBC library decide column data length?
If I use union in my select command.
string id;
select << "SELECT ID+'X'+'Y' as ID FROM A " \
" UNION"\
"SELECT ID from B",
into(id),
range(0, 1);
ID column in table A is varchar(3) and in table B is char(10).
The data length in first sql will be 5(3+'XY') and I found I only get the first 5 characters in second sql.
If I change select command to
select << "SELECT ID from B" \
" UNION"\
"SELECT ID+'X'+'Y' as ID FROM A ",
into(id),
range(0, 1);
It works fine.
In my case, does POCO uses first sql to decide the internal buffer length to retrieve data?

alex
Posts: 1294
Joined: 11 Jul 2006, 16:27
Location: United_States

Re: Question about POCO ODBC Library

Postby alex » 24 Jan 2014, 03:28

boriskao wrote:Sybase ODBC driver will return -1 if there is no data return for select command(Freetds return 0).
static_cast -1 to size_t will be 18446744073709551615.
In easysoft website, it says SQLRowCount return -1 for select in most ODBC drivers.
http://www.easysoft.com/support/kb/kb00939.html

Poco::Data::Statement::execute() documentation wrote:/// Returns the number of rows extracted from the database (for statements
/// returning data) or number of rows affected (for all other statements).

For better or worse, that's how it is; when you abstract, it is inevitable that some back-end-specific details will lost.

boriskao wrote:My second question is about how does POCO ODBC library decide column data length?
...
In my case, does POCO uses first sql to decide the internal buffer length to retrieve data?

No, POCO does not get involved with the intricacies of SQL statement parsing. Whatever your driver returns is what you get.

boriskao
Posts: 2
Joined: 22 Jan 2014, 14:10

Re: Question about POCO ODBC Library

Postby boriskao » 06 Feb 2014, 02:58

Thanks Alex

I write a small program to test bulk insert but I got core dump.

Session session("ODBC", "DSN=TEST;UID=TEST;PWD=TEST");
typedef Poco::Tuple<int,int,int> Person;
typedef std::vector<Person> People;
People P;
std::vector<int> arg1(20000);
std::vector<int> arg2(20000);
std::vector<int> arg3(20000);
for(int i=0;i<20000;++i) {
arg1[i]=i;
arg2[i]=i;
arg3[i]=i;

//P.push_back(Person(i,i,i));
}
session.setFeature("autoCommit", false);
session.setFeature("autoBind", true);
session.setFeature("autoExtract", true);
session << "INSERT INTO Person VALUES(?, ?, ?)",use(arg1,bulk) , use(arg2,bulk),use(arg3,bulk), now;

if i < 20000, it doesn't generate a core dump file.
if i > 20000, it generates a core dump file( Segmentation fault). The same result of Sybase ODBC and freetds drivers.
If I uncomment P.push_back(Person(i,i,i)), it runs well even i > 20000.
How do I debug this problem is from POCO or ODBC driver?
The gdb backtrace log as attached file.
Thanks.
Attachments
backtrace.zip
gdb backtrace
(795 Bytes) Downloaded 35 times


Return to “Support”

Who is online

Users browsing this forum: No registered users and 2 guests