Preferably without editing the stored procedure, is it possible that the output messages are displayed after every stored procedure completes execution, instead of at the very end?
For example, the following script (that calls an SP to insert 300K+ rows per day) will display the 4 output messages (300230 rows affected) once all SPs execute or if the process is cancelled.
exec usp_UpdateSales '11/21/2022'
exec usp_UpdateSales '11/22/2022'
exec usp_UpdateSales '11/23/2022'
exec usp_UpdateSales '11/24/2022'
Instead of showing the output messages at the end, is it possible that is displays the messages after the execution of each call?
I was reading about RAISERROR, but I'm not certain how to implement it into an SP call.
The SSIS Execute SQL Task does not hook the InfoMessage event. What you want from a problem statement, is to capture the messages printed to the screen in other applications.
As #AlwaysLearning points out, the approach is to create your own Script Task that runs your statement and then "does the thing" with the feedback from your stored procedure https://learn.microsoft.com/en-us/dotnet/api/microsoft.data.sqlclient.sqlconnection.infomessage
Some related sample bits of code to give you a solid shove in the right direction
c# - SqlConnection InfoMessage triggering only at end of execution
Accessing InfoMessages for SQL Server queries in C#
Ado.net Fill method not throwing error on running a Stored Procedure that does not exist
Related
We have a stored procedure that fires off a thousand emails. It's auto-run at 1 AM every night. I have to edit the stored procedure in Management Studio: I know I have to choose "Modify" and then make the edits, but I don't want to click "Execute" to save it, or the emailing sequence will start. How can I save the new code without executing the stored procedure? Thank you
Clicking Execute doesn't execute the procedure itself, it executes only SQL command altering the procedure.
You can check it by creating some mock stored procedure that is meant to just add some data to table and check if it adds that data when you click Execute in Modify window.
Clicking Execute won't actually run the procedure, it just applies your modifications.
Comment out the part that triggers the emails to be sent then execute, if you would prefer to see what it does first. Then when you are comfortable, uncomment and make your changes.
I have a system set up with a batch execution of a stored procedure 10 times.
exec procedure 1
exec procedure 2
exec procedure 3
exec procedure 4
...
exec procedure 10
The procedure is designed to accumulate a running total based on the ID of the record in a target table.
When I run that batch I will get results that are out of sync. The running total should just be the running total of the previous row, plus the value of the current row.
When I run the same batch with a GO statement in between each, it takes much longer to run, but executes correctly.
Is there any kind of hint (like "MAXDOP 1") that can be done in this situation to force the procedures to execute and complete in order without going out of sync?
I should add that the stored procedure being called, calls several procedures itself. If that has any bearing on a solution.
I did a bit more testing on this, and it looks like my initial thoughts were incorrect. I did several tests with batches using GO statements, and even then, only a few records in the batch would have their running balances updated, but the remaining would stay out of sync. It looks like when I did my initial tests, the first 10 records updated properly, but I didn't notice anything else in that section since the rest of the values were already correct until a later section of the data set.
This looks like it is an issue internal to the procedure, not repeated execution of the procedure. The weird part is that we never experienced this issue on a single-core system which is what still leaves to me thinking this is a parallelism issue, but most likely internal to the procedure.
Sorry for wasting your time.
I have a long-running SP (it can run for up to several minutes) that basically performs a number of cleanup operations on various tables within a transaction. I'm trying to determine the best way to somehow pass human-readable status information back to the caller on what step of the process the SP is currently performing.
Because the entire SP runs inside a single transaction, I can't write this information back to a status table and then read it from another thread unless I use NOLOCK to read it, which I consider a last resort since:
NOLOCK can cause other data inconsistency issues; and
this places the onus on anyone wanting to read the status table that they need to use NOLOCK because the table or row(s) could be locked for quite a while.
Is there any way to issue a single command (or EXEC a second SP) within a transaction and tell specify that that particular command shouldn't be part of the transaction? Or is there some other way for ADO.NET to gain insight into this long-running SP to see what it is currently doing?
You can PRINT messages in T-SQL and get them delivered to your SqlConnection in ADO.NET via the "InfoMessage" event. See
http://msdn.microsoft.com/en-us/library/a0hee08w.aspx
for details.
You could try using RAISERROR (use a severity of 10 or lower) within the procedure to return informational messages.
Example:
RAISERROR(N'Step 5 completed.', 10, 1) WITH NOWAIT;
I have an existing SQL 2005 stored procedure that for some reason, outputs its results in the Messages pane in SSMS instead of the Results pane. (Its actually a CLR procedure already compiled and deployed to all our servers, and used for another daily process. So I can't change it, I just want to use its output.)
For the sake of discussion, here's a stored proc that behaves the same way:
CREATE PROCEDURE [dbo].[OutputTest]
#Param1 int, #Param2 varchar(100)
AS
BEGIN
SET NOCOUNT ON;
PRINT 'C,10000,15000';
PRINT 'D,30000,90000';
PRINT 'E,500,50000';
END
So no actual SELECT statement in there, and if you run this, you'll see these results only on the Messages pane.
Is there any way for me to use these results as part of a larger query? Put them in a temp table or something, so I can parse them out?
None of the "normal stuff" works, because there is no true "output" here:
INSERT INTO #output
EXEC OutputTest 100, 'bob'
just shows
C,10000,15000
D,30000,90000
E,500,50000
(0 row(s) affected)
on the messages pane, and the temp table doesn't actually get anything put into it.
Can you execute the stored proc from C# code? If so, you might be able to hook into the SqlCommand event called SqlInfoMessage:
SqlConnection _con = new SqlConnection("server=.;
database=Northwind;integrated Security=SSPI;");
_con.InfoMessage += new SqlInfoMessageEventHandler(_con_InfoMessage);
The event handler will look like this:
static void _con_InfoMessage(object sender, SqlInfoMessageEventArgs e)
{
string myMsg = e.Message;
}
The "e.Message" is the message printed out to the message window in SQL Server Mgmt Studio.
While it won't be pretty and might require some ugly parsing code, at least you could get a hold of those messages that way, I hope!
Marc
You cannot trap, catch or use these messages from within SQL Server. You can, however, receive them from within a client application.
I don't think there is a way but even if there is I think you should seriously consider whether it is a good idea. This sounds like a fudge which can only cause you pain in the long term. Creating an alternative proc that does exactly what you want sounds to me like a better plan.
there is no way to get messages from the message pane in your result.
if you think about it the SSMS is just a client that parses those messages the way you see it.
if you wan to use them in your app take a look at Connection Events in ADO.NET
The only way I could think that this might be possible is if the output is printed via the RAISERROR command. In that case, you might be able to capture it elsewhere using TRY/CATCH.
But that's just an idea: I've never done it. In fact, the only thing we do that's remotely close is that we have a command line tool to run stored procedures in batch jobs rather than using sql server agent to schedule them. This way all of our nightly jobs are scheduled in one place (the windows task scheduler) rather than two, and the command line tool captures the anything printed to the message window into a common logging system that we monitor. So some of procedures will output quite a lot of detail to that window.
I am wondering if it is possible to see stored procs that are being executed by other stored procs in Sql Server Profiler, is it possible, and if so how?
If you profile using the SP::Starting event, you can see all the stored procedures that are executed. You want to make sure to get a couple of the profile columns included:
NestLevel - This shows the nesting level of SPs calling each other - so if Test calls EmbeddedTest then the SP::Starting event for Test wil show NestLevel=1 and the event for EmbeddedTest will show NestLevel=2
ObjectName - This shows the name of the stored procedure being executed
SPID - Session ID for the connection
So to find a calling sequence you need to look for an event with NestLevel greater then 1 and then look for the NestLevel=1 on the same SPID that preceeded the call. Of course this works for deeper nesting levels as well.