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 > |