How Do You NOT Rollback Some Code In Nested Procedures?
Apr 29, 2008
I have a procedure that calls other procedures which in turn call other procedures. I have a transaction in the first procedure since I want to rollback everything done if something goes wrong except for rows inserted in a loggtable in my database. The reason for this is that all error shall be saved in this table, otherwise there is no way to find out what error occured.
begin try declare @param2 int begin transaction exec proc2 @param2 commit transaction end try begin catch if @@trancount > 0 rollback transaction end catch
i haven't had an opportunity to do this before. I have nested stored proc and both inserts values into different tables. To maintain atomicity i want to be able to rollback everything if an error occurs in the inner or outer stored procedure.
I need to execute 10 stored procedures one after the other in a sequence,but need to roll back if any one of them fails and discontinue further execution.Example: if sp#3 fails it should roll back alll the changes made by sp# 1 and sp# 2 and also should not continue executing the rest of them. Any ideas? Thanks.
The attempt to create the following stored procedure, which is supposed to call the previously created stored procedures inside it, causes the following errors.
Server: Msg 137, Level 15, State 2, Line 1 Must declare the variable '@OfferIDTwo'. Server: Msg 137, Level 15, State 2, Line 1 Must declare the variable '@OfferIDThree'. Server: Msg 137, Level 15, State 2, Line 1 Must declare the variable '@OfferID'. Server: Msg 137, Level 15, State 2, Line 1 Must declare the variable '@OfferID'. Server: Msg 137, Level 15, State 2, Line 1 Must declare the variable '@OfferID'. Server: Msg 137, Level 15, State 2, Line 1 Must declare the variable '@OfferID'.
Create Procedure spPrepareOfferSimulation @OfferIDOne int As exec spPopulateOfferTables @OfferID go exec spPopulateOfferProduct @OfferID go exec spPopulateOfferDictionary @OfferID go exec spPopulateOfferCondition @OfferID go exec spPopulateOfferError @OfferID go exec spPopulateOfferLimit @OfferID go exec spPopulateOfferQA @OfferID go
Can someone provide me with some productive input to fix this mess?
I have a caller stored procedure (sp_A) which calls several stored procedures (sp_1,sp_2,sp_3,sp_4, sp_5)
The statements in the called stored procedures sp_1 to sp_5 are all contained within BEGIN TRY -- BEGIN TRAN and BEGIN CATCH blocks which ensure that any errors in the SQL statements are rolled back when an error occurs.
However, I have noticed that when the called stored procedure fails, the caller procedure does not fail Rather it continues processing the remaining sps. I want to add code in my calling sp to stop this fom happening. Any ideas?
I have used this statement within my calling sp but no joy yet.
I need the output of a stored procedure in another SP. That's simple (using a temporary table). But there's a small (big error ) problem.
Since I have to manually define the temporary table with it's fields and datatype to recieve the output from the nested SP , this approach would fail if, in the future more parameters are required to be returned . Is it possible to immunise my SP to such a consequence at creation time, rather them having to amend the temporary table later ?
Any idea how to overcome the above problem ? Is there a way that the temporary table can be automatically created like we have in a SQL statement with the INTO keyword. Any ideas ?
I have a stored procedure that returns a scalar value and I want to use that value (among other places) within another stored procedure.
-- The general purpose stored procedure is far too long to include here but I've included the last several lines of code at the bottom to show general gist of it and how it exits.-- The only way I can find to use that returned value "criteria" in a stored procedure is to define a temporary table, INSERT it into the table and then extract it from the temprary table into the variable where I actually wanted it.... i.e.
DECLARE @CriteriaTable TABLE ( Criteria VARCHAR(8000) )INSERT INTO @CriteriaTable (Criteria) EXEC psp_WRP_DisplayCriteria @UserID, 'Dealers, Prefix, Serial Range, Models, Makes, Sold Date', @UserGroup SELECT @Criteria=Criteria FROM @CriteriaTable
This seems like a ridiculously long winded and confusing way of doing things, especially since Im doing it in a dozen different procedures, half a dozen reports and 1 (so fasr) asp.net/VB web site - and I can't help thinking there must be a better way using just one or even zero extra lines of code to do this. e.g. SELECT@Criteria = (EXEC dbo.psp etc...) ... or some variation thereof with the correct syntax.
or even better going to where that variable is used and changing ... EXEC dbo.[psp_InsertWarrantyReportTracking] @UserID = @UserID , @ReportName = 'rptChassisTrackExtdWarranty', -- <------ @ReportCriteria = @Criteria to ... EXEC dbo.[psp_InsertWarrantyReportTracking] @UserID = @UserID , @ReportName = 'rptChassisTrackExtdWarranty', -- <------ @ReportCriteria = (EXEC dbo.psp_ etc...)... or some variation thereof with the correct syntax.
But no matter how I try and how I search I can't find any way other than in what is otherwise a completely supefluous temporary table.
Am I missing something or is that REALLY the only way to get a hold of that returned value?
------ Last portion of the general purpose routine I'm trying to call ---------------------If Patindex('%RO Audit%',@Parmlist) > 0 Begin set @Criteria = @Criteria + '- RO Audit date' select @All=ROAuditAll, @From = ROAuditFrom, @To = ROAuditTo from dbo.tblWRParameters where @UserID = UserName If @All = 1 set @Criteria = @Criteria + '- ALL' + @NL else set @Criteria = @Criteria + 'is between ' + rtrim(@From) + ' and ' + rtrim(@to) + @NL END
--Return the combined parameter field select @Criteria as Criteria
Has anyone faced problems in calling one stored procedure from within another stored procedure ? I am considering using nested SPs, and would appreciate any inputs on it.
I have nested a Stored Procedure within a stored procedure. The nested stored procedure ends in a select statement. What I'd like to do is either capture the results of the select statement (it will be 1 row with 3 columns, I only need the contents of first column), or suppress the select statement from displaying in the final results of the Stored Procedure it is nested in.
For every trigger and stored procedure I have a try-catch that writes to an error_log table. The problem is the inner error is not preserved, always get: The current transaction cannot be committed and cannot support operations that write to the log file. Roll back the transaction.
As seen below - though commented out: I tried commiting any transactions - though I didn't create one. I played with the XACT_STATE though that was 0 My test case was last procedure has 1/0
ALTER Trigger [trg_ActivityLogEntryReportsError] ON [dbo].[ActivityLog] FOR INSERT AS
DECLARE @ActivityLogID int ,@AlertMessageTypeID int ,@comment nvarchar(max) ,@Error_Source nvarchar(max) --- etc. SELECT @ActivityLogID = ActivityLogID ,@AlertMessageTypeID = AlertMessageTypeID ,@Comment = Comment FROM INSERTED BEGIN TRY
if @AlertMessageTypeID = 2 -- activity reported an error begin exec proc_CreateAlertLogEntry_forError @ActivityLogID ,@Comment
update ActivityLog set flgActivityChecked = 1 where @activityLogId = activityLogID end END TRY
BEGIN CATCH select @Error_Source = 'trg_ActivityLogEntryReportsError ' ,@Error_Procedure = ERROR_Procedure() --- etc. INSERT INTO ERROR_LOG ( Error_Source ,Error_Procedure ,Error_Message --- etc. ) VALUES ( @Error_Source ,@Error_Procedure ,@Error_Message ---etc. ,@Error_Comment ) -- if @@TRANCOUNT > 0 --begin --commit --end END CATCH
Step 2)
/* This will be called by a Trigger */ ALTER Procedure [dbo].[proc_CreateAlertLogEntry_forError] (@ActivityLogID int ,@Comment nvarchar(max)) AS
Declare @ProcessScheduleID int ,@ProcessID int --,@comment nvarchar(max) ,@Error_Source nvarchar(max) ---etc BEGIN TRY insert into AlertLog ( AlertMessageTypeID ,comment ,ActivityLogID ) values ( 2 -- error ,@comment ,@ActivityLogID )
select @Error_Source = 'trg_AlertLogEntry_SendsOnInsert ' ,@Error_Procedure = ERROR_Procedure() ,@Error_Message = ERROR_MESSAGE() --- etc. INSERT INTO ERROR_LOG ( Error_Source ,Error_Procedure -- etc.) VALUES ( @Error_Source ,@Error_Procedure ,@Error_Message ---etc.) -- if @@TRANCOUNT > 0 --begin --commit --end END CATCH
STEP 4
ALTER Procedure [dbo].[proc_SendEmail] ( @AlertLogID Int ,@AlertMessageTypeID int ,@Comment nvarchar(max) = '' ,@ActivityLogID int = -1 )
AS
declare @AlertSubject nvarchar(512) ,@AlertBody nvarchar(max) ,@myQuery nvarchar(512) ,@profile_name1 nvarchar(128) ,@return_value int ,@mymailitem int ,@Error_Source nvarchar(max) ---etc. ,@Error_Comment nvarchar(max) ,@Test int /* @return_value int -- not using at this point but 0 is OK 1 is failure @mymailitem int -- not using now could store mailitem_id which is on msdb.dbo.sysmail_mailitems sysmail_mailitems.sent_status could be either 0 new, not sent, 1 sent, 2 failure or 3 retry. */
select top 1 @profile_name1 = [name] from msdb.dbo.sysmail_profile order by profile_id
I am currently developing a project that requires a server level permission for one stored procedure (ALTER ANY LOGIN)
To this effect, I plan to create a certificate, sign the stored procedure with it, import the certificate into the master DB and assign privileges.
I also understand that modification to the code invalidates the signature (after all thats the point of signing something).
But what about user defined functions and stored procedures referenced by the signed procedure? Does SQL server follow the dependancy chain and include referenced procedures in the signature? Or does the privilege assigned to the certificate not apply when the nested procedure is executed?
If this is not the case couldn't a restricted database user just alter a nested stored procedure they have been granted ALTER access to and make themselves SA or something?
So to sum up, do you have to duplicate the functionality of otherwise nested procedures into a certificate signed procedure to protect server security?
We are migrating a SQL 6.5 application with 1900 stored procedures that use 100's of temp tables to SQL 2000.
A problem we have encountered was that we started out getting an "invalid column" errors on certain procedures. Investigation determined that the error was being generated in a nested procedure. The table that caused the error ended up being a temp table that was created using "select into". The following select statement from that temp table gave the invalid column error.
First thinking it was the "Select Into" we then discovered that the outer most procedure had created a temp table of the same name prior to executing the lower level procedure. After the select into, the next statement was a SELECT that went against what it thought was the inner temp table. However, it grabbed the outermost temp table and then couldn't find the appropriate columns and generated the error.
The solution, of course, was to rename the inner most temp table. We also remove the "select into" in the procedure by explicitly creating the temp table.
We tried creating some test procedures to attempt to reproduce this scenario without complete success.
Our test created 3 procedures (sp1 calling sp2 calling sp3) to mimic the current scenario. Sp1 created a temp table and executed sp2, which executed sp3. Sp3 created another temp table using the same name as the one created in sp1.
If we create all three procedures at the same time, it doesn't matter if we change the order in which they are created or whether we create the inner temp table explicitly or with a "select into", SQL Query Analyzer won't let us create the procedure because it finds that the temp table has been declared twice. If we create the procedures separately however, they compile and allow sp3 to create a temp table by the same name as sp1. After creating the procedures independently, they runs properly in all cases with everything in proper scope and no problems.
Admittedly, this is bad coding to start with, but what is happening with the scope of the temp tables within the stored procedures?
Hi,I'm adapting access queries to sql server and I have difficulties withthe following pattern :query1 : SELECT * FROM Query2 WHERE A=@param1query 2: SELECT * FROM Table2 WHERE B=@param2The queries are nested, and they both use parameters.In MS Acccess the management of nested queries with parameters is soeasy (implicit declaration of parameters, transmission of parametersfrom main query to nested query)that I don't know what the syntax should be for stored procedures.The corresponding stored procedure would be something likeCREATE TABLE #TempTable (...table definition...)INSERT INTO #TempTable ExecProc spQuery2 @Param2SELECT * FROM #TempTable WHERE A=@Param1And spQuery2 would be : SELECT * FROM Table2 WHERE B=@ParamI was wondering if this syntax would work and if I can skip theexplicit declaration of #TempTable definition.Thanks for your suggestions.
Hi there,I have a data manipulation process written in a Nested Stored procedurethat have four levels deeper. When I run these individual proceduresindividually they all seems to be fine. Where as when I run them alltogether as Nested proces (calling one in another as sub-procedures) Logfile is growing pretty bad like 25 to 30GB.. and finally getting kickedafter running disk space. This process is running around 3hrs on a SQLserever Standard Box having dual processer and 2gb ram.This procedures have bunch of bulk updates and at least one cursor ineacch procedure that gets looped through.I was wondering if anybody experienced this situation or have any clueas to why is this happening and how to resolve this?I am in a pretty bad shape to deliver this product and in need of urgenthelp.Any ideas would be greatly appreciated..Thanks in advance*** Sent via Developersdex http://www.developersdex.com ***
We have a required to run multiple procedures in Single Go . And Error Occurred in any Procedure the it will rollback all the changes( Either all Proc run or None)
Problem Statement is its not capturing the Error Message from Either Proc1 or Proc 2., its Capturing the Flat Message (The current transaction cannot be committed and cannot support operations that write to the log file. Roll back the transaction). How do i capture the Error Occurred in Proc 1 or Proc 2 into Log Tables.
I had developed all my reports using CRXI and stored procedures of MSSQL 2000. Now I am migrating from CRXI to SSRS. But i have a problem because of my report stored procedures. These stored procedures are complex and nested. When i try to use procedures in a report, it gives a error. When i comment out my EXEC line in my procedures, it goes OK.
Consider a situation where a stored procedure taking a varbinary(max) (BLOB) input parameter then calls a nested stored procedure and passes along that varbinary(max) as an input parameter to the nested stored procedure.
Is a copy of the BLOB provided to the nested stored procedure (passed by value) OR is the BLOB passed by reference.
My interest is in understanding the potential memory hit when handling large BLOBs in this environment.
For example, if the BLOB is 200MB, will SQL server need to allocate memory for a new copy each time it's passed to another stored procedure?
Looks like table type parameters are passed by reference, but I haven't been able to find any info on BLOBS in this context.
Hi everyone,I would like to back up my whole database project inclkuding the codeofstored procedures in my application.Is there a waa to get the code of all stored procedures of a databaseprojectwith a SQL-statement or otherwise using a normal database-connection ?Hope someone can help.Best regards,Daniel
Hi,We're having a big discussion with a customer about where to store the SQL and DML statements. (We're talking about SQL Server 2000)We're convinced that having all statements in the code (data access layer) is a good manner, because all logic is in the "same place" and it's easier to debug. Also you can only have more problems in the deployment if you use the stored procedures. The customer says they want everything in seperate stored procedures because "they always did it that way". What i mean by using seperate stored procedures is:- Creating a stored procedure for each DML operation and for each table (Insert, update or delete)- It should accept a parameter for each column of the table you want to manipulate (delete statement: id only)- The body contains a DML statement that uses the parameters- In code you use the name of the stored procedure instead of the statement, and the parameters remain... (we are using microsoft's enterprise library for data access btw)For select statements they think our approach is best...I know stored procedures are compiled and thus should be faster, but I guess that is not a good argument as it is a for an ASP.NET application and you would not notice any difference in terms of speed anyway. We are not anti-stored-procedures, eg for large operations on a lot of records they probably will be a lot better.Anyone knows what other pro's are related to stored procedures? Or to our way? Please tell me what you think...Thanks
Is there a way, through t-sql or through SQL Server Management Studio, to retrieve (or export to file) all procedure code for all my stored procedures?
I have some lengthy code that creates a #Temp file. I would like to access this code from different stored procedures. Is there such a thing as an INCLUDE statement for stored procedures, or is this what the EXEC statement accomplishes?
Hi all, if have problem to display error message in vb.net that comes from a stored procedure. IF ...... then msgbox "ERROR at Update" returnvalue = SUCCES ELSE Msgbox "Successfull Updated" returnvalue = ERROREND IFHow can I return values from Stored Procedure to VB.NET and then give to User a Message that the Update was successful or not.Thanks to all
I have several stored procedures with a similar query. The SELECT clauses are identical, but the FROM and WHERE clauses are different.
Since the SELECT clause is long and complicated (and often changes), I want to place the SELECT clause in a separate file and then have the stored procedures include the block of text for the SELECT clause when they compile.
Is this possible? Looking through the docs and searching online, I don't see any way to do this.
I am in the position where I have to transfer data from an old database schema to a new database schema. During the transfer process alot of logic has to be performed so that the old data gets inserted into the new tables and are efficiently done so that all foreign keys are remained and newly created keys (as the new schema is Normalised alot more) are correct.
Is it best if I perform all this logic in a Stored Procedure or in C# code (where the queries will also be run)?
Hi.here is my code with my problem described in the syntax.I am using asp.net 1.1 and VB.NETThanks in advance for your help.I am still a beginner and I know that your time is precious. I would really appreciate it if you could "fill" my example function with the right code that returns the new ID of the newly inserted row. Public Function howToReturnID(ByVal aCompany As String, ByVal aName As String) As Integer 'that is the variable for the new id.Dim intNewID As Integer Dim strSQL As String = "INSERT INTO tblAnfragen(aCompany, aName)" & _ "VALUES (@aCompany, @aName); SELECT @NewID = @@identity" Dim dbConnection As SqlConnection = New SqlConnection(connectionString)Dim dbCommand As SqlCommand = New SqlCommand()dbCommand.CommandText = strSQL 'Here is my problem.'What do I have to do in order to add the parameter @NewID and'how do I read and return the value of @NewID within that function howToReturnID'any help is greatly appreciated!'I cannot use SPs in this application - have to do it this way! :-( dbCommand.Parameters.Add("@aFirma", aCompany.Trim)dbCommand.Parameters.Add("@aAnsprAnrede", aName.Trim) dbCommand.Connection = dbConnection TrydbConnection.Open()dbCommand.ExecuteNonQuery() 'here i want to return the new ID!Return intNewID Catch ex As Exception Throw New System.Exception("Error: " & ex.Message.ToString()) Finally dbCommand.Dispose()dbConnection.Close()dbConnection.Dispose() End Try End Function
Hi all - I'm trying to optimized my stored procedures to be a bit easier to maintain, and am sure this is possible, not am very unclear on the syntax to doing this correctly. For example, I have a simple stored procedure that takes a string as a parameter, and returns its resolved index that corresponds to a record in my database. ie exec dbo.DeriveStatusID 'Created' returns an int value as 1 (performed by "SELECT statusID FROM statusList WHERE statusName= 'Created') but I also have a second stored procedure that needs to make reference to this procedure first, in order to resolve an id - ie: exec dbo.AddProduct_Insert 'widget1' which currently performs:SET @statusID = (SELECT statusID FROM statusList WHERE statusName='Created')INSERT INTO Products (productname, statusID) VALUES (''widget1', @statusID) I want to simply the insert to perform (in one sproc): SET @statusID = EXEC deriveStatusID ('Created')INSERT INTO Products (productname, statusID) VALUES (''widget1', @statusID) This works fine if I call this stored procedure in code first, then pass it to the second stored procedure, but NOT if it is reference in the second stored procedure directly (I end up with an empty value for @statusID in this example). My actual "Insert" stored procedures are far more complicated, but I am working towards lightening the business logic in my application ( it shouldn't have to pre-vet the data prior to executing a valid insert). Hopefully this makes some sense - it doesn't seem right to me that this is impossible, and am fairly sure I'm just missing some simple syntax - can anyone assist?