View previous topic :: View next topic |
Author |
Message |
pdwalker
Joined: 09 Aug 2005 Posts: 22
|
Posted: Sun Aug 21, 2005 19:53 Post subject: NWNX ODBC Improvement? |
|
|
Hi,
I've been having a fiddle with the NWNX ODBC interface and I've noticed one thing that I think could be used to improve how the inerface operates
With SELECT statements, you can use the SQLFetch function to determine if your select statement returned any rows.
Unfortunately, with UPDATEs, you do not get any feedback as to whether the updated succeeded (e.g. when updating a non existing record set). As a result a select has to be coded in, tested for an error and then the choice between an update or insert decided. This results in double the number of queries that have to be run in order update records.
Would it be possible to return an value to indicate the success or failure of a statement to avoid this extra coding?
e.g. (using SetPersistentString as an example)
Code: |
string sSQL = "SELECT player FROM " + sTable + " WHERE player='" + sPlayer +
"' AND tag='" + sTag + "' AND name='" + sVarName + "'";
SQLExecDirect(sSQL);
if (SQLFetch() == SQL_SUCCESS)
{
// row exists
sSQL = "UPDATE " + sTable + " SET val='" + sValue +
"',expire=" + IntToString(iExpiration) + " WHERE player='" + sPlayer +
"' AND tag='" + sTag + "' AND name='" + sVarName + "'";
SQLExecDirect(sSQL);
}
else
{
// row doesn't exist
sSQL = "INSERT INTO " + sTable + " (player,tag,name,val,expire) VALUES" +
"('" + sPlayer + "','" + sTag + "','" + sVarName + "','" +
sValue + "'," + IntToString(iExpiration) + ")";
SQLExecDirect(sSQL);
}
|
becomes
Code: |
sSQL = "UPDATE " + sTable + " SET val='" + sValue +
"',expire=" + IntToString(iExpiration) + " WHERE player='" + sPlayer +
"' AND tag='" + sTag + "' AND name='" + sVarName + "'";
if (SQLExecDirect(sSQL))
{
// error, record not updated, insert it instead as it probably does not exist
sSQL = "INSERT INTO " + sTable + " (player,tag,name,val,expire) VALUES" +
"('" + sPlayer + "','" + sTag + "','" + sVarName + "','" +
sValue + "'," + IntToString(iExpiration) + ")";
SQLExecDirect(sSQL);
}
|
The first bit of code always runs two queries.
The second bit of code only runs two queries for newly created records. In a persistent world where more values would be updated rather than inserted, it results in half the number of queries.
It is possible that this functionality exists and that I have missed it, so I would love to have someone point it out to me.
Comments? Suggestions?
Thanks in advance.
- Paul |
|
Back to top |
|
|
Papillon x-man
Joined: 28 Dec 2004 Posts: 1060 Location: Germany
|
Posted: Mon Aug 22, 2005 14:01 Post subject: |
|
|
From the top of my head I'd say that UPDATE and INSERT do not return result values. I can see some issues about interpreting a zero result (as is the case in your update example) as an error, but the idea itself is good. _________________ Papillon |
|
Back to top |
|
|
pdwalker
Joined: 09 Aug 2005 Posts: 22
|
Posted: Mon Aug 22, 2005 16:06 Post subject: |
|
|
Typically, the convention for inserts, deletes, updates and selects is to return the number of rows inserted, deleted, affected or selected.
This is the case with JDBC.
I've just peaked into the odbc api's and...ack! The api seems a little clunky to me. It looks like you would have to fiddle with the SQLGetDiagRec function to get more useful information (maybe, not sure - didnt read further)
The SQLExecDirect function does at least return an error if the statement fails, so in the case of updates, you can use that error as a guide that you have to follow it up with an insert.
I see from the docs that:
Quote: | If SQLExecDirect executes a searched update or delete statement that does not affect any rows at the data source, the call to SQLExecDirect returns SQL_NO_DATA. |
This information could be used to eliminate the redundant selects before updates.
- Paul |
|
Back to top |
|
|
Lokey
Joined: 02 Jan 2005 Posts: 158
|
Posted: Wed Aug 24, 2005 7:08 Post subject: Kneejerk reaction |
|
|
I don't really follow why you set up your SQL statements that way though.
It'll make the SQL statement more messy, but won't require multiple connects if you just did:
INSERT (statement) ON DUPLICATE KEY UPDATE (statement); _________________ Neversummer PW NWNx powered mayhem |
|
Back to top |
|
|
Vladiat0r
Joined: 17 Jun 2005 Posts: 25
|
Posted: Wed Aug 24, 2005 11:06 Post subject: Re: Kneejerk reaction |
|
|
Lokey wrote: | I don't really follow why you set up your SQL statements that way though.
It'll make the SQL statement more messy, but won't require multiple connects if you just did:
INSERT (statement) ON DUPLICATE KEY UPDATE (statement); | I believe it's because this requires minimum version MySQL 4.1
Who knows what other Databases support this? |
|
Back to top |
|
|
pdwalker
Joined: 09 Aug 2005 Posts: 22
|
Posted: Wed Aug 24, 2005 17:44 Post subject: Re: Kneejerk reaction |
|
|
Lokey wrote: | I don't really follow why you set up your SQL statements that way though.
It'll make the SQL statement more messy, but won't require multiple connects if you just did:
INSERT (statement) ON DUPLICATE KEY UPDATE (statement); |
It is non standard SQL and does not work with Oracle, SQL Server or Postgres. Good enough reason not to use it, but instead use the more conventional syntax.
- Paul |
|
Back to top |
|
|
Gryphyn
Joined: 20 Jan 2005 Posts: 431
|
Posted: Fri Aug 26, 2005 7:04 Post subject: |
|
|
There is a MySQL API call that returns just this data.
MySQL Reference Manual :: 24.2.7.1 mysql_stmt_affected_rows()
mysql_stmt_affected_rows() my_ulonglong mysql_stmt_affected_rows(MYSQL_STMT *stmt) Description Returns ... be called immediately after mysql_stmt_execute() for UPDATE , DELETE , or INSERT statements. For SELECT statements, mysql_stmt_affected_rows() works like mysql_num_rows() . This function was added in MySQL 4.1.0. Return Values An integer greater than zero
This could possibly be added as an extra 'NWNX_Function'.
The result could even be used to control 'loops', as you know how many records were/are affected.
Cheers
Gryphyn |
|
Back to top |
|
|
Acrodania
Joined: 02 Jan 2005 Posts: 208
|
Posted: Fri Aug 26, 2005 17:57 Post subject: |
|
|
The important line being right here.....
Gryphyn wrote: |
There is a MySQL API call that returns just this data.
This function was added in MySQL 4.1.0. Return Values An integer greater than zero
|
All but one of the NWNX installs I know of are running 4.0.XX, plus that series is still considered "current".
API calls that are not used in current implementations shouldn't be added by default... |
|
Back to top |
|
|
|