Do I have to include "SELECT ##RowCount" if I have more than one SQL statement? - sql

I know that, if I execute a single SQL statement that UPDATEs or DELETEs some data, that it will return the number of rows affected.
But if I have multiple SQL statements in a sql script, and I want to know the number of rows affected from the last statement executed, will it still return that automatically, or do I need a
SELECT ##RowCount
at the end of the script?
The code in question is not a Stored Procedure. Rather, it is a parameterized SQL script stored in an arbitrary location, executed using the ExecuteStoreCommand function in Entity Framework, as in:
var numberOfRowsAffected = context.ExecuteStoreCommand<int>(mySqlScript, parameters);

It depends on the NOCOUNT setting when executing your quer(y/ies).
If NOCOUNT is ON then no DONE_IN_PROC messages will NOT be returned.
If NOCOUNT is OFF, the default setting, then DONE_IN_PROC messages will be returned, (eg. counts).
Both of these situations are different to executing,
SELECT ##ROWCOUNT;
which will return a result set with a single scalar value, different from a DONE_IN_PROC message. This will occur, regardless of the setting of NOCOUNT.
I believe that SELECT ##ROWCOUNT is sometimes used to make Entity Framework "play" with more complex TSQL statements because EF both requires
Requires a count for post validation
And will accept a scalar number result set as a substitute for a DONE_IN_PROC message.
Its important that SELECT ##ROWCOUNT; is executed immediately after the last query statement because many statements will reset ##ROWCOUNT and therefore yield an unexpected result.

Just to be specific on answer part, you would need to add SELECT ##RowCount to return number of rows affected by last statement.
I think confusion might be due to rows returned in SSMS window while executing query.By default SSMS shows number of rows returned for all sql statements but it returns affected rows as message not a dataset.

##ROWCOUNT will automatically return number of rows effected by the last statement.
Please find the msdn link here
https://msdn.microsoft.com/en-us/library/ms187316.aspx

Related

How ##rowcount works if two queries executed simultaneously in two query windows?

I want to use ##rowcount to track rows processed. But I have question if one statement is executed and taking long time, meanwhile if other query executed in other query window will it affect ##rowcount value of first one?
How ##rowcount will behave in this scenario?
Database: SQL Server
It will give the corresponding rows affected for the two queries. Two windows here, are effectively two sessions. So they are not affected in any way whatsoever.
##ROWCOUNT is both scope and connection safe.
In fact, it reads only the last statement row count for that connection and scope. The full rules are here on MSDN (cursors, DML, EXECUTE etc)
To use it in subsequent statements, you need to store it in a local variable.

What is the DB2 equivalent of SQL Server's SET NOCOUNT ON?

What is the DB2 equivalent of SQL Server's SET NOCOUNT ON?
"From the SQL Server documentation:
SET NOCOUNT ON... Stops the message that shows the count of the number of rows affected by a Transact-SQL statement or stored procedure from being returned as part of the result set...
For stored procedures that contain several statements that do not return much actual data, or for procedures that contain Transact-SQL loops, setting SET NOCOUNT to ON can provide a significant performance boost, because network traffic is greatly reduced."
my problem is if I update a row in a table, a trigger runs that update another
row in a different table.
In Hibernate I get this error: "Batch update returned unexpected row
count from update; actual row count: 2; expected: 1".
I think because of the trigger DB2 returns 2 instead of 1, what
is correct. However, is there any way to make DB2 to return 1
without removing the trigger or can I disable the check in Hibernate?
How to handle this issue?
Can anyone plz tell "Set NoCount on"(sql server) equivalent in db2?
There is no equivalent to SET NOCOUNT in DB2 because DB2 does not produce any informational messages after a DML statement has completed successfully. Instead, the DB2 driver stores that type of information in a local, connection-specific data structure called the SQL communications area (SQLCA). It is up to the application (or whatever database framework or API the application is using) to decide which SQLCA variables to examine after executing each statement.
In your case, your application has delegated its database interaction to Hibernate, which compares the number of affected rows reported by DB2 in the SQLCA with the number of rows Hibernate expected its UPDATE statement to change. Since Hibernate isn't aware of the AFTER UPDATE trigger you created, it expects the update statement to affect only one row, but the SQLCA shows that two rows were updated (one by Hibernate's update statement, and one by the AFTER UPDATE trigger on that table), so Hibernate throws an exception to complain about the discrepancy.
This leaves you with two options:
Drop the trigger from that table and instead define an equivalent followup action in Hibernate. This is not an ideal solution if other applications that don't use Hibernate are also updating the table in question, but that's the sort of decision a team gets to make when they inflict Hibernate on a database.
Keep the AFTER UPDATE trigger where it is in DB2, and examine your options for defining Hibernate object mappings to determine if there's a way to at least temporarily disable Hibernate's row count verification logic. One approach that looks particularly encouraging is to specify the ResultCheckStyle.NONE option as part of a custom #SQLUpdate annotation.
For SQL Server and Sybase, there appears to be a third option: Hide the activity of an AFTER UPDATE trigger from Hibernate by activating SET NOCOUNT ON within the trigger. Unfortunately, there is no equivalent in DB2 (or Oracle, for that matter) that allows an application to selectively skip certain activities when tallying the number of affected rows.

How does updating or inserting while looping through a result set affect the result set itself?

suppose I fetch an RS, based on certain conditions and start looping though it , then , on certain situations , I update insert or delete records, which may have been part of this RS, using separate prepared statements.
How does this effect the result set ? My inclination is to think that since the Statement which fetched this RS was executed earlier in the process, this RS will now be blind to the changes made by my prepared statements.
Pseudocode :
Preapare Statement ps1
execute ps1 -> get Result Set rs1
loop through rs1
{
Update or delete records using other prepared statements
}
Read Consistency
Oracle guarantees that the set of data seen by a statement is consistent with respect to a single point in time and does not change during statement execution (statement-level read consistency)
That is why, If you have a query such as
insert into t
select * from t;
Oracle will simply duplicate all rows without going into an infinite loop or raising an error.
There are other implications because of this.
1) Oracle reads from the rollback segment to provide you with this read-consistent image of your data. So, if your rollback segments are nor correctly sized, or you commit across fetches, you'll get the "Snapshot too old" error, since your rollback data is no longer available.
Ok , so if that is the case , is it possible to refresh it while making updates ? I mean aside from making the cursor updateable and using the inbuilt functions of the result set.
2) Each query sees the data at the point of time it began. If by refresh you mean refiring the query, then the data you see might be different again, if you do commits in your pl/sql body or within a pl/sql loop or if some other transactions are running in your system concurrently.
It doesn't. The result set of a query/cursor is kept by the database, even if you alter or remove the rows that are the base of this result set. So you are correct, it is blind to changes made after the statement is executed.

Getting the ROWCOUNT value (not ##ROWCOUNT) in SQL

Is there a way to see what ROWCOUNT is set to?
The component that is used to call my stored procedure has an option to limit how many rows are returned, but it apparently does that by setting ROWCOUNT. One stored procedure only returns a single aggregated row, but the intermediate queries sometimes return more than the limit and are getting truncated. The function that does all of this is generic and is used to call other stored procedures; some my other procedures may need the limit.
Right now I am setting ROWCOUNT to a very large number at the top of my stored procedure and then setting it back to the (hard-coded) regular limit before I return my result. I don't maintain the component that calls my stored procedures so I may not know if the returned row limit is changed. What I'd like to do is set a local variable to the current ROWCOUNT value, and then set it back at the end. Is there any way to actually see what ROWCOUNT is set to?
If you query the sys.dm_exec_sessions dmv it will return the number of rows returned on the session up to this point (should of course be the same as ##rowcount).
SELECT row_count FROM sys.dm_exec_sessions
WHERE session_id = ##spid
You might be able to play around with that to see if you can use it
Right now I am setting ROWCOUNT to a very large number at the top of my stored procedure
You can also just do SET ROWCOUNT 0, in this case it will return all rows
Stop using SET ROWCOUNT. It's being partially deprecated anyway.
Use TOP which has been there since SQL Server 2000: 11 years. This is per query and does not affect intermediate rows which means you can appyl it when needed, not globally as you are now.
Edit, Feb 2012
It's being removed in the next release after SQL Server 2012 too for insert, update and delete

How can I get the number of records affected by a stored procedure?

For INSERT, UPDATE and DELETE SQL statements executed directly against the database, most database providers return the count of rows affected. For stored procedures, the number of records affected is always -1.
How do we get the number of records affected by a stored procedure?
Register an out parameter for the stored procedure, and set the value based on ##ROWCOUNT if using SQL Server. Use SQL%ROWCOUNT if you are using Oracle.
Mind that if you have multiple INSERT/UPDATE/DELETE, you'll need a variable to store the result from ##ROWCOUNT for each operation.
##RowCount will give you the number of records affected by a SQL Statement.
The ##RowCount works only if you issue it immediately afterwards. So if you are trapping errors, you have to do it on the same line. If you split it up, you will miss out on whichever one you put second.
SELECT #NumRowsChanged = ##ROWCOUNT, #ErrorCode = ##ERROR
If you have multiple statements, you will have to capture the number of rows affected for each one and add them up.
SELECT #NumRowsChanged = #NumRowsChanged + ##ROWCOUNT, #ErrorCode = ##ERROR
Turns out for me that SET NOCOUNT ON was set in the stored procedure script (by default on SQL Server Management Studio) and SqlCommand.ExecuteNonQuery(); always returned -1.
I just set it off: SET NOCOUNT OFF without needing to use ##ROWCOUNT.
More details found here : SqlCommand.ExecuteNonQuery Method#Remarks
When SET NOCOUNT ON is set on the connection (before or as part of executing the command, or as part of a trigger initiated by the execution of the command) the rows affected by individual statements stop contributing to the count of rows affected that is returned by this method.
If no statements are detected that contribute to the count, the return value is -1. If a rollback occurs, the return value is also -1.
For Microsoft SQL Server you can return the ##ROWCOUNT variable to return the number of rows affected by the last statement in the stored procedure.
##ROWCOUNT
WARNING: ##ROWCOUNT may return bogus data if the table being altered has triggers attached to it!
The ##ROWCOUNT will return the number of records affected by the TRIGGER, not the actual statement!