Re: [Cppcms-users] cppdb::statement copy and assign
Brought to you by:
artyom-beilis
|
From: Artyom B. <art...@ya...> - 2015-11-12 08:45:19
|
Can you show the full code (- you can hide passwords in connection strings)?
First of all it looks like you bind two parameters when 3 are required. i.e.
cppdb::statement st=se.create_prepared_uncached_statement("UPDATE t SET c2=? WHERE c1=? AND c2=?") << 'xx' << 2;
And what is 'xx'? It isn't even C++.
Also you probably what to call se.create_statement()
create_prepared_uncached_statement is for execution of a prepared statement many times but not letting it into cache (for example for insert on many rows one time)
create_statement - creates ordinary unprepared statement (it still uses binding) good for one time calls of custom statement or rare statements
create_prepared_statement - creates prepared statement and caches it for future reuse (default) statements that are eused frequently.
Artyom Beilis
----- Original Message -----
> From: CN <cn...@fa...>
> To: cpp...@li...
> Cc:
> Sent: Thursday, November 12, 2015 10:22 AM
> Subject: Re: [Cppcms-users] cppdb::statement copy and assign
>
>T hank you for the reply!
>
> Having received your message, I went back and study frontend.* and
> backend.* of cppdb source code trying to understand more about it.
> According to my findings so far, instances of cppdb::statement in
> backend indeed are reference counted, meaning to me that these objects
> will not be destroyed as long as they are still referenced.
>
> But I can only go that deep into cppdb source. Because my original
> troublesome code actually uses uncached statement but I do not fully
> understand cppdb's statement cache mechanism, I begin to suspect this
> part of cppdb.
>
> I know this is not professional attitude, but the simplified version of
> my troublesome code follows:
>
> cppdb::statement create(cppdb::session &se)
> {
> cppdb::statement st=se.create_prepared_uncached_statement(
> "UPDATE t SET c2=? WHERE c1=? AND c2=?")
> << 'xx' << 2;
> return st;
> }
>
> void use()
> {
> cppdb::session se("connection params");
> cppdb::statement st=create(se);
> cppdb::transaction tx(se);
> st.exec(); //Weird error occurs here.
> //Do more SQL here like this:
> //se << "INSERT INTO ...";
> tx.commit();
> }
>
> Note that the data type of t.c2 is INTEGER.
>
> And the PostgreSQL error log follows:
>
> 2015-10-31 14:20:42 CST ERROR: invalid input syntax for integer:
> "cppdb_psqlstmt_17"
> 2015-10-31 14:20:42 CST STATEMENT: UPDATE t SET c2=$1 WHERE c1=$2 AND
> c2=$3
> 2015-10-31 19:46:26 CST ERROR: invalid input syntax for integer: ""
> 2015-10-31 19:46:26 CST STATEMENT: UPDATE t SET c2=$1 WHERE c1=$2 AND
> c2=$3
> 2015-10-31 22:42:24 CST ERROR: invalid input syntax for integer: ""
> 2015-10-31 22:42:24 CST STATEMENT: UPDATE t SET c2=$1 WHERE c1=$2 AND
> c2=$3
> 2015-10-31 22:55:28 CST ERROR: invalid input syntax for integer: "!"
> 2015-10-31 22:55:28 CST STATEMENT: UPDATE t SET c2=$1 WHERE c1=$2 AND
> c2=$3
>
> As one might notice: How could I bind "cppdb_psqlstmt_17" to
> cppdb::statement's parameters?
> PostgreSQL complained weird arguments passed to c2 when the same
> cppdb::statement::exec() was called repeatedly.
>
> Any idea? Please!
>
> Best Regards,
> CN
>
>
> On Thu, Nov 12, 2015, at 12:47 AM, Artyom Beilis wrote:
>> Actually you are mistaken.
>>
>> cppdb::statement, cppdb::session and cppdb::result keep the reference to
>> underlying
>> backed object representing them.
>>
>> See:
>>
> http://cppcms.com/sql/cppdb/classcppdb_1_1statement.html#adc5ddc1e8df9248b74692990cffe40cf
>>
>> So copy is totally valid and you can use it this way without problems.
>>
>> Actually statement would also keep a track of the session and result of
>> statement and session as
>> well.
>>
>> So it is correct way to do things.
>>
>> Of course it is bad idea to start using copies of came cppdb::statement
>> from two
>> different locations simultaneously.
>>
>> So look for the problem in some other place.
>>
>> Artyom
>>
>>
>> > Hi!
>> >
>> > I recently made a mistake by doing this:
>> >
>> > cppdb::statement create(){
>> > cppdb::session se("connect parameters");
>> > cppdb::statement st=se << "SELECT * FROM t";
>> > return st;
>> > }
>> >
>> > void use(){
>> > cppdb::statement st=create();
>> > st.query();
>> > }
>> >
>> > Very weird errors happens to st.query().
>> > It took me quite some time to pin point the bug. After that, I re-read
>> > the comments in cppdb/cppdb/frontend.h and I believe they confirm my
>> > conclusion:
>> >
>> > The problem here, I believe, is that cppdb::statement object is
> already
>> > destroyed before st.query() is executed.
>> >
>> > I am writing this note here in order to remind myself of avoiding such
>> > practice. Hopefully no one else will make the same mistake as I did!
>> >
>> > Meanwhile, I suspect it will be better off
>> >
>> > (a) either to remove the cppdb::statement copy and assignment methods
>> > from cppdb source altogether
>> > (b) or to make cppdb::statement non-copyable
>> >
>> > I have a feeling that these two methods serve only as a trap.
>> > Yes? No?
>> >
>> > Best Regards,
>> > CN
>> >
>> > --
>> > http://www.fastmail.com - Access all of your messages and folders
>> > wherever you are
>> >
>> >
>> >
> ------------------------------------------------------------------------------
>> > _______________________________________________
>> > Cppcms-users mailing list
>> > Cpp...@li...
>> > https://lists.sourceforge.net/lists/listinfo/cppcms-users
>> >
>>
>>
> ------------------------------------------------------------------------------
>> _______________________________________________
>> Cppcms-users mailing list
>> Cpp...@li...
>> https://lists.sourceforge.net/lists/listinfo/cppcms-users
>
> --
> http://www.fastmail.com - Access your email from home and the web
>
>
>
> ------------------------------------------------------------------------------
> _______________________________________________
> Cppcms-users mailing list
> Cpp...@li...
> https://lists.sourceforge.net/lists/listinfo/cppcms-users
>
|