Can I call SQLExecute after SQLFreeStmt without SQLPrepare? - odbc

I have the following sequence of code calls:
SQLPrepare
SQLExecute(hstmt, SQL_CLOSE);
SQLFreeStmt
//It works till here
SQLExecute //Now it fails.
Why am I required to call SQLPrepare again, I just freed the cursor. I shouldn't prepare the SQL statement again.

The correct behaviour is that SQLPrepare/SQLExecute/SQLFreStmt(stmt, SQL_CLOSE) should allow another SQLExecute on the same stmt handle without re-preparing. You can see this as a valid state transition in the ODBC Programmers Guide. You might use this sequence if you had done a SQLPrepare(sql) and only fetched some of the rows (instead of all of them) as without the SQLFreeStmt(stmt, SQL_CLOSE) or fetching until SQL_NO_DATA was returned you'd get an invalid cursor state if you issued another SQLExecute. SQLFreeStmt(stmt, SQL_DROP) is equivalent to SQLFreeHandle(SQL_HANDLESTMT,stmt) and frees the entire stmt handle meaning you cannot use it again at all.

SQLFreeStmt(hstmt, SQL_CLOSE) cleans up everything to do with that statement handle, take a look at the summary:
SQLFreeStmt stops processing
associated with a specific statement,
closes any open cursors associated
with the statement, discards pending
results, or, optionally, frees all
resources associated with the
statement handle.
If you don't want to use SQLPrepare again you can use SQLExecDirect instead.

Related

Can we compile procedure or function if there is DDL lock on that procedure?

procedure cannot be compiled? it is just running and nothing happened.
and I have try following code to check whether any block session make this. but I did not find any blocked session.
select
*
from
v$session
where
blocking_session is not NULL
order by
blocking_session;
You won't find it as a blocking session, nor in gv$lock, because it's a library object lock rather than a data object lock. Instead, look at gv$access and/or dba_ddl_locks. You can also look at gv$session for a plsql_object_id or plsql_entry_object_id matching the object_id of your procedure in either dba_objects or dba_procedures. That's not a sure-fire way of catching everything though, if you have chained PL/SQL calls... but gv$access and/or dba_ddl_locks will have what you need for sure.
If something is executing your procedure, you will have to wait for them to complete, or kill their session, before you can compile it. It's a weak point in Oracle, that prevents us from pushing code changes in without kicking everybody out first. But that's the way it is.
I found that there is a lot of rows in the table and whenever I try to compile procedure it can call that table too. So I Stop the compilation process at that time and execute the rollback statement. Therefore it takes time to rollback milions of rows one by one I have tracked those process through the following script.
select s.sid, s.serial#, s.client_info, t.addr, sum(t.used_ublk)
from v$transaction t, v$session s
where t.addr = s.taddr
group by s.sid, s.serial#, s.client_info, t.addr;
I just need to wait and might be I did not find any idea about to do anything except waiting. When all the transactions are rollbacked then I try to compile it and it compiled.

What happens if we don't delete object handle? How it affects? How do we see that? - PROGRESS 4GL

I am using below query which has handle but I can see nothing happens even if I delete/not delete the object of the handle. But everyone says always delete the object finally. Why we need to delete them? what happens if we don't delete them? How do we see that ?
finally:
if valid-handle(hQueryTest) then delete object hQueryTest no-error.
if valid-handle(hQuerytestvalue) then delete object hQuerytestvalue no-error.
end finally.
OpenEdge simply does not have a reference count based garbage collector for handle based objects. So the object the query handle points to will remain in memory of the AVM forever. If that's on an AppServer, the memory consumption of the AppServer process may grow slightly but steadily.
OpenEdge has the concept of WIDGET-POOLs that can support with memory management.
You can check the DynObjects.* Log-entry-type to get insights into the Life-Time of dynamic objects, handle-based or class-based.

Having trouble understanding FLWOR expressions combined with inserts and return statements [duplicate]

I recognized that (insert/delete)-XQueries executed with the BaseX client always returning an empty string. I find this very confusing or unintuitive.
Is there a way to find out if the query was "successful" without querying the database again (and using potentially buggy "transitive" logic like "if I deleted a node, there must be 'oldNodeCount-1' nodes in the XML")?
XQuery Update statements do not return anything -- that's how they are defined. But you're not the only one who does not like those restrictions, and BaseX added two ways around this limitation:
Returning Results
By default, it is not possible to mix different types of expressions
in a query result. The outermost expression of a query must either be
a collection of updating or non-updating expressions. But there are
two ways out:
The BaseX-specific update:output() function bridges this gap: it caches the results of its arguments at runtime and returns them after
all updates have been processed. The following example performs an
update and returns a success message:
update:output("Update successful."), insert node <c/> into doc('factbook')/mondial
With the MIXUPDATES option, all updating constraints will be turned off. Returned nodes will be copied before they are modified by
updating expressions. An error is raised if items are returned within
a transform expression.
If you want to modify nodes in main memory, you can use the transform
expression.
The transform expression will not help you, as you seem to modify the data on disk. Enabling MIXUPDATES allows you to both update the document and return something at the same time, for example running something like
let $node := <c/>
return ($node, insert node $node into doc('factbook')/mondial)
MIXUPDATES allows you to return something which can be further processed. Results are copied before being returned, if you run multiple updates operations and do not get the expected results, make sure you got the concept of the pending update list.
The db:output() function intentionally breaks its interface contract: it is defined to be an updating function (not having any output), but at the same time it prints some information to the query info. You cannot further process these results, but the output can help you debugging some issues.
Pending Update List
Both ways, you will not be able to have an immediate result from the update, you have to add something on your own -- and be aware updates are not visible until the pending update list is applied, ie. after the query finished.
Compatibility
Obviously, these options are BaseX-specific. If you strongly require compatible and standard XQuery, you cannot use these expressions.

How to return results together with update operations in BaseX?

I recognized that (insert/delete)-XQueries executed with the BaseX client always returning an empty string. I find this very confusing or unintuitive.
Is there a way to find out if the query was "successful" without querying the database again (and using potentially buggy "transitive" logic like "if I deleted a node, there must be 'oldNodeCount-1' nodes in the XML")?
XQuery Update statements do not return anything -- that's how they are defined. But you're not the only one who does not like those restrictions, and BaseX added two ways around this limitation:
Returning Results
By default, it is not possible to mix different types of expressions
in a query result. The outermost expression of a query must either be
a collection of updating or non-updating expressions. But there are
two ways out:
The BaseX-specific update:output() function bridges this gap: it caches the results of its arguments at runtime and returns them after
all updates have been processed. The following example performs an
update and returns a success message:
update:output("Update successful."), insert node <c/> into doc('factbook')/mondial
With the MIXUPDATES option, all updating constraints will be turned off. Returned nodes will be copied before they are modified by
updating expressions. An error is raised if items are returned within
a transform expression.
If you want to modify nodes in main memory, you can use the transform
expression.
The transform expression will not help you, as you seem to modify the data on disk. Enabling MIXUPDATES allows you to both update the document and return something at the same time, for example running something like
let $node := <c/>
return ($node, insert node $node into doc('factbook')/mondial)
MIXUPDATES allows you to return something which can be further processed. Results are copied before being returned, if you run multiple updates operations and do not get the expected results, make sure you got the concept of the pending update list.
The db:output() function intentionally breaks its interface contract: it is defined to be an updating function (not having any output), but at the same time it prints some information to the query info. You cannot further process these results, but the output can help you debugging some issues.
Pending Update List
Both ways, you will not be able to have an immediate result from the update, you have to add something on your own -- and be aware updates are not visible until the pending update list is applied, ie. after the query finished.
Compatibility
Obviously, these options are BaseX-specific. If you strongly require compatible and standard XQuery, you cannot use these expressions.

What is the default value of sqlite3_busy_timeout?

This seems like it should be really easy to find out, but I don't see it documented anywhere. If I open a sqlite connection and begin a transaction without specifying a timeout by calling sqlite3_busy_timeout, what default value is used? Or will this somehow cause undefined behavior? The documentation of this method doesn't say.
My specific use case is the version bundled with iOS, but I'm guessing the answer is pretty much the same across platforms.
If neither sqlite3_busy_timeout() nor sqlite3_busy_handler() are set and a writer is active then step() returns SQLITE_BUSY immediately.
Note: In some cases SQLITE_IOERR_BLOCKED is returned
See also: Register A Callback To Handle SQLITE_BUSY Errors in the second paragraph where it states
If the busy callback is NULL, then SQLITE_BUSY or SQLITE_IOERR_BLOCKED is returned immediately upon encountering the lock. If the busy callback is not NULL, then the callback might be invoked with two arguments.
You can try doing this:
sqlite> PRAGMA busy_timeout = 30000;
It sets the busy_timeout pragma to 30 seconds.
https://www.sqlite.org/pragma.html#pragma_busy_timeout
From what I've read (the default is 0) which I assume is either immediate busy response or unlimited waiting. Docs don't say. However I am seeing when multiple processes write to db, they will sometimes throw a BUSY error.

Resources