I have a stored procedure in a loop that is called about 100 times for about fifteen minutes; once per day. The stored procedure contains deletion statements. What is the best practice for error handling on the client side after executing the stored procedure.
I simply use On Error Resume Next meaning if the stored procedure fails or times out; it is simply called again on the next iteration. I have 'SET XACT_ABORT ON' in the stored procedure to ensure that the explicit transaction in the stored procedure is rolled back if the command object times out in VB6. The stored procedure passes an error code as an output variable back to the program; but I am wandering if anything else is required.
Related
In my code, I often use nested stored procedures. The processing of my stored procedures all perform several operations in the database, so they are encapsulated in a transaction. My stored procedures children can also be performed as a parent. I therefore start all my procedures stored as a child by a BEGIN TRAN after the BEGIN TRY and in case of error, I test the following condition before rollback: IF ##trancount = 1 and xact_state()<>0. My question is, when I perform an EXECUTE of a stored procedure, is that the value of #trancount can be changed by another EXECUTE, apart from internal or external stored procedure calls.
Example:
the stored procedure A calls the stored procedure B
the stored procedure C does not use any other stored procedure
The processing of each stored procedure is encapsulated in a transaction
Is that, in the same session the present case can occur:
I execute the stored procedure A, the value of ##trancount changes to 1 and then to 2 after the BEGIN TRAN of the stored procedure B
Now, let’s imagine that my procedure is not finished but, at the same time, the SQL Server engine executes the procedure stored C on the same session. Is the value of #trancount after the BEGIN TRAN of the stored procedure C is 1 or 3?
I have two TSQL EXEC statements
EXECUTE (N'MyDynamicallyGeneratedStoredProcedure') -- return 0 on success
SELECT #errCode = ##ERROR ;
IF (#errCode = 0)
BEGIN
EXEC 'A Sql Statement using ##temptable created from first', #returnValue
END
How do I make the two EXEC's synchronous? ; Right now the second EXEC does not wait for the first EXECUTE to complete. I tried issuing a WaitFor Delay, It waits but the second EXEC statement is never returing back.
Thanks.
Update, Here is more info:
First execute creates a global temp table and populates it from a complex SELECT query.
Second EXEC is a CLR Stored Procedure that generates a dynamic SP, based on the variables from recently created and populated Global Temp table.
Now the second EXEC, complains that the Global Temp table is not found.
Update 2, Found the issue (And its me!!)
GBN (and others) was point blank on the answer. EXEC IS synchronous. The problem? My understanding of the problem itself.. I had mentioned
EXECUTE (N'MyDynamicallyGeneratedStoredProcedure') -- return 0 on success
It should have been:
1(a) EXECUTE (N'CreateMyDynamicStoredProcedure') -- return 0 on success
1(b) EXECUTE (N'MyDynamicStoredProcedure') -- return 0 on success
I missed that 1(b) was actually executed somewhere else and after step (2) .
(I should go get a life!!)
EXECUTE is sychronous. The 2nd one runs after the 1st one. Always.
Do you have multiple connections running the same code? You are using a global temp table that will be visible to all connections so it may look like asyncc execution...
As gbn's answer has pointed out, EXECUTE is synchronous.
The problem might be that your SQL Connection object within CRL stored procedure is not in the same context as your batch script. Your global temporary table should have been dropped after running EXECUTE (N'MyDynamicallyGeneratedStoredProcedure')
Make sure that you create your SQLConnection object by passing "context connection=true"
Here is the post answer where someone had a similar problem accessing temporary table since SQLConnection was not in the same connection context.
Accessing TSQL created #temp tables from CLR stored procedure. Is it possible?
If your second CRL stored procedure runs through a different connection, CRL sproc will not be able to access the global temp table since it should have been dropped.
Refer to this post on Global Temporary life cycle (when the gloal temp is dropped)
Deleting Global Temporary Tables (##tempTable) in SQL Server
If a stored procedure contains multiple statements e.g. first an insert, then an update and finally a deletes and the stored procedure gets killed in the middle of the delete, does the insert and update also have to be rolled back? Or does it only roll back the delete i.e. the implicit transaction?
As explained in Transactions, each statement will be executed as an implicit transaction. If a statement fails then the effect of prior statements will remain committed.
Note that the entire stored procedure may be executed within an explicit transaction created by the calling code.
insert and update have to be commited but delete Statement was rolled back
since you have no explicit BEGIN TRANSACTION in the stored procedure, each statement will run on its own with no ability to rollback any changes if there is an error.
However, if before you call the stored procedure you issue a BEGIN TRANSACTION, then all statements are grouped within a transaction and can either be COMMITted or ROLLBACKed following stored procedure execution.
Reference: KM.
How does SQL Server treat statements inside stored procedures with respect to transactions?
I have a stored procedure (simplified version) as below. In general it will push the pending items to email queue and update the status of those items to pushed. This stored procedure has been called in a 60 seconds interval.
ALTER PROCEDURE [dbo].[CreateEmailQueue]
AS
BEGIN
insert into EmailQueue
select *
from actionstatus
where actionstatus='Pending'
update actionstatus
set actionstatus = 'Pushed'
where actionstatus = 'Pending'
END
It works fine but I found one exception record. The exception's action status has been changed to "Pushed" but the record did not appear in the EmailQueue. I suspected that the action status record has been generated after the insert but before the update. But I am not 100% sure as I assume that SQL Server always execute a stored procedure in an isolation block so the data change won't affect the data set inside the execution. Could someone help explain the actual process inside the stored procedure, review this stored procedure and advise if it is OK, or it should be put in a transaction block? and, any performance or locking issue for doing this in transaction? Thanks for your input.
You must use transactins inside stored procedure. SQL Server don't generate transactions for stored procedures calls automatically. You can simply check it by execute code something like taht:
insert ...
--this will falls
select 1/0
Insertion will be done and than you'll have division by zero error
I have got a stored procedure in SQL Server 2008 and it does quite a fair amount of inserting / deleting / updating operations.
Now I am wondering if there would be any way that I might be able to detect whether or not a stored procedure has completed ALL Inserting / Deleting / Updating operations.
Also, I understand that there can be a returned value from a stored procedure, which in this case here can be a statusCode (0/1). But through some of my experiments, I found that the statusCode always would get returned immediately once the execution of the stored procedure was finished, while in the mean time, inserting / deleting / updating was actually still running. So what should I do here to see the statusCode only get returned when inserting / deleting / updating operations have all been completed?
Thanks.
Code Structure:
BEGIN
DECLARE #statusCode
SET #statusCode = 0
-- Loop through all tables in a given database
-- using cursor
-- do Insert / Update/ Delete operations
SET #statusCode = 1
SELECT #statusCode
END
If the stored procedure returns, all operations for that call are complete.
You have not seen operations continuing after a stored procedure finishes unless another connection is making changes too. For one, it would break A in ACID