Обсуждение: ERROR with "Update ... where Current of"
Hi,
after a lot of studying i couldn't find out what's going wrong with my
positioned update. Whatever i have tried: SQLGetDiagRec reports: Error:
"Cursor C1 does not exists"
Here is my Code (a simplified example from MS):
...
SQLRETURN = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmtSelect);
SQLRETURN = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmtUpdate);
SQLRETURN = SQLSetCursorName(hstmtSelect, "C1", SQL_NTS);
SQLRETURN = SQLExecDirect(hstmtSelect,
"SELECT NAME, PHONE FROM CUSTOMERS",SQL_NTS);
/* in the example, a SQLBindCol followed here ... */
SQLRETURN = SQLFetch(hstmtSelect);
/* positioned update : set first customers phonenumber to empty */
SQLRETURN = SQLExecDirect(hstmtUpdate,
"UPDATE EMPLOYEE SET PHONE=\"\" WHERE CURRENT OF C1",SQL_NTS);
...SQLRETURN is set to -1, SQLGetDiagRec reports Error: "Cursor >>C1<< does
not exist"
...
psqlodbc30a.dll ist directly linked.
Here is what i have tried:
- Reading, exploring, reading, ...
- Select ... for Update
- connection Parameter UpdatableCursors=1;
- connection Parameter Autocommit off
- connection Parameter UseDeclareFetch=1
- Select ... for Update
- Select ... with hold
- older odbc Driver 8.04
- explict BEGIN
Any help would be greatly appreciated!
--
View this message in context:
http://postgresql.1045698.n5.nabble.com/ERROR-with-Update-where-Current-of-tp4499184p4499184.html
Sent from the PostgreSQL - odbc mailing list archive at Nabble.com.
Hi, Unfortunately the psqlodbc driver doesn't support POSITIONED UPDATE. regards, Hiroshi Inoue (2011/06/18 0:51), BGoebel wrote: > Hi, > > after a lot of studying i couldn't find out what's going wrong with my > positioned update. Whatever i have tried: SQLGetDiagRec reports: Error: > "Cursor C1 does not exists" > > Here is my Code (a simplified example from MS): > ... > SQLRETURN = SQLAllocHandle(SQL_HANDLE_STMT, hdbc,&hstmtSelect); > SQLRETURN = SQLAllocHandle(SQL_HANDLE_STMT, hdbc,&hstmtUpdate); > SQLRETURN = SQLSetCursorName(hstmtSelect, "C1", SQL_NTS); > > SQLRETURN = SQLExecDirect(hstmtSelect, > "SELECT NAME, PHONE FROM CUSTOMERS",SQL_NTS); > /* in the example, a SQLBindCol followed here ... */ > SQLRETURN = SQLFetch(hstmtSelect); > /* positioned update : set first customers phonenumber to empty */ > SQLRETURN = SQLExecDirect(hstmtUpdate, > "UPDATE EMPLOYEE SET PHONE=\"\" WHERE CURRENT OF C1",SQL_NTS); > > ...SQLRETURN is set to -1, SQLGetDiagRec reports Error: "Cursor>>C1<< does > not exist" > ... > psqlodbc30a.dll ist directly linked. > > Here is what i have tried: > - Reading, exploring, reading, ... > - Select ... for Update > - connection Parameter UpdatableCursors=1; > - connection Parameter Autocommit off > - connection Parameter UseDeclareFetch=1 > - Select ... for Update > - Select ... with hold > - older odbc Driver 8.04 > - explict BEGIN > > > Any help would be greatly appreciated! > > > > > -- > View this message in context: http://postgresql.1045698.n5.nabble.com/ERROR-with-Update-where-Current-of-tp4499184p4499184.html > Sent from the PostgreSQL - odbc mailing list archive at Nabble.com.
Hi, thank you a lot for your message. ... a more appropriate error message by the ODBC-Driver would have been very nice. I will try to implement an update via SQLSetPos with SQL_UPDATE using a keyset_driven Cursor as it is described at http://msdn.microsoft.com/en-us/library/ms715392(v=vs.85).aspx. Does any docu exists, what is (not) implemented by the ODBC driver? regards -- View this message in context: http://postgresql.1045698.n5.nabble.com/ERROR-with-Update-where-Current-of-tp4499184p4510135.html Sent from the PostgreSQL - odbc mailing list archive at Nabble.com.
This is the solution what i have found for my postioned update problem
It is implemented in Pascal/Delphi. To keep it short(er) i ommitted some
code (Error handling, setting String-length for returned data, type Info.
OK, "Update ... where Current of" would have been more elegant, but the
mean thing is: it works.
Thanks goes to Mr. Inoue for the hint, that SQLSetStmtAttr(...
SQL_CONCUR_ROWVER ...) is needed.
----------------------- snip ---------------
Var aRes:Integer;
hStmtSelect,hstmtUpdate,fEnvHandle,fConnectHandle:SQLHandle;
szName:ShortString;
cbName:SQLInteger;
aScroll,aSQLSmallInt:SQLSmallInt;
aConnectString:String;
aRow:Cardinal;
// -UpdatableCursors=1/0 makes no difference
// -using SQL_CURSOR_Static : Update works. DB2 Says NO.
Begin
fEnvHandle := 0;
fConnectHandle := 0;
aRes := SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, fEnvHandle);
aRes := SQLAllocHandle(SQL_HANDLE_DBC, fEnvHandle, fConnectHandle);
aSqlSmallint := 0;
aConnectString :=
'Driver={PostgreSQL};Server=127.0.0.1;Port=5432;Database=postgres;Uid=postgres;Pwd=mypwd;UpdatableCursors=1;';
aRes := SQLDriverConnect(fConnectHandle,
GetDesktopWindow,
@aConnectString[1],
length(aConnectString),
nil,
0,
aSqlSmallint,
0);
//switchin AUTOCOMMIT off
aRes := SQLSetConnectAttr(fConnectHandle,
SQL_ATTR_AUTOCOMMIT,
pointer(SQL_AUTOCOMMIT_OFF),
sizeof(SQL_AUTOCOMMIT_OFF));
aRes:= SQLAllocHandle(SQL_HANDLE_STMT, fConnectHandle, hStmtSelect);
// Cursor : KeySetDriven + SQL_CONCUR_ROWVER(=updatable)
aRes:= sqlSetStmtAttr(hStmtSelect,
SQL_ATTR_CONCURRENCY,
pointer(SQL_CONCUR_ROWVER),
sizeof(SQLSmallint));
aRes:= sqlSetStmtAttr(hStmtSelect,
SQL_ATTR_CURSOR_TYPE,
//pointer(SQL_CURSOR_STATIC), // would work
for updates with PostGreSQL. DB2: non updatable
pointer(SQL_CURSOR_KEYSET_DRIVEN),
sizeof(SQLSmallint));
// Select ...
aRes := SQLExecDirect(hstmtSelect,
pchar('SELECT name FROM customers order by nr'),
SQL_NTS);
// fetch will read name
aRes:= SQLBindCol(hstmtSelect, 1, SQL_C_CHAR, @szName[1], 50, cbName);
// fetching/reading the first row
aRow := 1;
aRes := SQLFetchScroll(hStmtSelect,
SQL_FETCH_ABSOLUTE,
arow);
// Changing data. Doing so, every time i call this snippet, the value will
be changed
szName[0]:=Chr(cbName);
IF szName[1]<'a'
THEN
szName := 'anyname'
ELSE
szName := 'ANYNAME';
cbName:=Length(szName);
// UPDATE data
aRes := SQLSetPos(hstmtSelect,
1,
SQL_UPDATE,
SQL_LOCK_UNLOCK );
// We are fetching the second row...
aRow:=2;
aRes := SQLFetchScroll(hStmtSelect,
SQL_FETCH_ABSOLUTE,
arow);
// ... and the first (changed) row again
// PostgreSQL: updated data in first row is shown, according to the ODBC
KeySetDriven property.
aRow:=1;
aRes := SQLFetchScroll(hStmtSelect,
SQL_FETCH_ABSOLUTE,
arow);
// Make changes visible to other users
// PostGreSQL: as expected: other users do not see the updates, when i do
not COMMIT them
aRes:=SQLExecDirect(hstmtUpdate,
'commit',
SQL_NTS);
// Does Fetch works without a new SELECT ?
// DB2: "...Ordinarily, all cursors close at the end of a transaction...",
there is an " with hold" Option.
// PostGreSQL : yes
aRow:=1;
aRes := SQLFetchScroll(hStmtSelect,
SQL_FETCH_ABSOLUTE,
arow);
end;
--
View this message in context:
http://postgresql.1045698.n5.nabble.com/ERROR-with-Update-where-Current-of-tp4499184p4553441.html
Sent from the PostgreSQL - odbc mailing list archive at Nabble.com.