How to "SET NOCOUNT ON" for Nhibernate generated select statements - nhibernate

We have "SET NOCOUNT OFF" by default on our database server.We use "SET NOCOUNT ON" for store procedures.
As reported by dba's that all nhibernate generated select statements are using "SET NOCOUNT OFF". Which is taking long for queries to execute.
We are trying to increase the performance.I can not figure out the way to set "SET NOCOUNT ON" for specific nhibernate session or query. Can someone have some opinion about that.
Regards

You probably misunderstand what SET NOCOUNT ON does and why.
SET NOCOUNT does not have such a significant effect that it becomes a concern. Setting it to ON on statements that DON'T return data is simply an optimization.
On the other hand, setting it to ON on queries, where you very much want to know how many results were returned, makes no sense. Instead of quickly detecting how many results there are, your client would have to enumerate all the data to see how many rows are returned.
Your server will return the data in any case, so telling it to NOT return the number of rows it returns makes no sense.
You probably have other performance issues. You should check what queries are executed, whether your tables have proper the indexes and whether you force NHibernate to execute more queries than you expect (the dreaded N+1 problem)

I can't give you the option in nhibernate to set nocount off, however I know nhibernate is depending on the count to check if the query was succesfull. When you return the wrong count (0), nhibernate will think something is wrong and throws an excetion.
Besides that I do not think you will gain a lot from setting nocount off.

Related

How can I ignore 'Arithmetic Overflow' related errors from within a data view?

I have a complex data view that recursively links and summarizes information.
Each night a scheduled task runs a stored procedure that selects all of the data from the data view, and inserts it into a table so that users can query and analyze the data much more quickly than running a select statement on the data view.
The parent table consists of a few hundred thousand records and the result set from the export is well over 1,000,000 records in size.
For most nights the exportation process works without any trouble, however, if a user enters an incorrect value within our master ERP system, it will crash the nightly process because one of the decimal fields will contain a value that doesn't fit within some of the conversions that I have to make on the data. Debugging and finding the specific, errant field can be very hard and time consuming.
With that said, I've read about the two SQL settings NUMERIC_ROUNDABORT and ARITHABORT. These sounds like the perfect options for solving my problem, however, I can't seem to get them to work with either my data view or stored procedure.
My stored procedure is nothing more than a TRUNCATE and INSERT statement. I appended...
SET NUMERIC_ROUNDABORT OFF
SET ARITHABORT OFF
... to the beginning of the SP and that didn't help. I assume this is because the error is technically taking place from within the code associated with the data view.
Next, I tried adding two extended properties to the Data View, hoping that that would work. It didn't.
Is there a way that I can set these SQL properties to ignore rounding errors so that I can export my data from my data view?
I know for most of us, as SO answerers, our first inclination is to ask for code. In this case, however, the code is both extremely complex and proprietary. I know fixing the definitions that cause the occasional overflow is the most ideal solution, but in this circumstance, it is much more efficient to just ignore these type of errors because they happen on such a rare basis and are so difficult to troubleshoot.
What can I do to ignore this behavior?
UPDATE
By chance, I believe I might have found the root cause of the issue, however, I have no idea why this would be occurring. It just doesn't make since.
Through out my table view, I have various fields that are calculated. Since these fields need to fit in fields within the table that are defined as decimal (12, 5), I always wrap the view field statements in a CAST( ... AS DECIMAL(12, 5)) clauses.
By chance, I stumbled upon an oddity. I decided to see how SSMS "saw" my data view. In the SSMS Object Explorer, I expanded the Views->[My View]-Columns section and I saw that one of the fields was defined as a decimal (13, 5).
I assumed that I must have made a mistake in one of my casting statements but after searching throughout the code for the table view, there is no definition for a decimal(13, 5) field?! My only guess is that the definition that SSMS sees of the view field must be derived from resulting data. However, I have no clue how this could happen since I each field to a decimal(12, 5).
I would like to know why this is happening but, again, my original question still stands. How and what SET statement can I define on a table view that will ignore all of thee arithmetic overflows and write a null value in the fields with errant data?
FINAL COMMENTS
I've marked HeavenCore's response as the answer because it does address my question but it hasn't solved my underlying problem.
After a bit of troubleshooting and attempts at trying to get my export to work, I'm going to have to try a different approach. I still can't get the export to work, even if I set the NUMERIC_ROUNDABORT and ARITHABORT properties to OFF.
i think ARITHABORT is your friend here.
For instance, using SET ARITHABORT OFF & SET ANSI_WARNINGS OFF will NULL the values it fails to cast (instead of throwing exceptions)
Here is a quick example:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[tbl_OverflowExample](
[Value] [decimal](12, 2) NULL
) ON [PRIMARY]
GO
INSERT [dbo].[tbl_OverflowExample] ([Value]) VALUES (CAST(9999999999.00 AS Decimal(12, 2)))
GO
INSERT [dbo].[tbl_OverflowExample] ([Value]) VALUES (CAST(1.10 AS Decimal(12, 2)))
GO
--#### Select data without any casting - works
SELECT VALUE
FROM dbo.tbl_OverflowExample
--#### With ARITHABORT and ANSI warnings disabled - Returns NULL for 999999 but 1.10 as expected
SET ARITHABORT OFF;
SET ANSI_WARNINGS OFF;
SELECT CONVERT(DECIMAL(3, 2), VALUE)
FROM dbo.tbl_OverflowExample
GO
--#### With defaults - Fails with overflow exception
SET ARITHABORT ON;
SET ANSI_WARNINGS ON;
SELECT CONVERT(DECIMAL(2, 2), VALUE)
FROM dbo.tbl_OverflowExample
Personally though - i'd prefer to debug the view and employ some CASE /.../ END statements to return NULL if the underlying value is greater than the target data type - this would ensure the view works regardless of the connection options.
EDIT: Corrected some factual errors

Is "SET NOCOUNT OFF" necessary in a stored procedure?

I have many procedures that has set nocount on.
Is it necessary to turn it off at the end of stored procedure?
e.g.:
create procedure DummyProc
as
begin
set nocount on
...
set nocount off
end
set nocount on will disable the X rows affected. message SQL returns. This message is suppressed, in some cases, due to undesired effects with the client executing the stored proc.
set nocount off will undo this suppression. However, set nocount on is a scope setting, and by default, will be turned off when leaving the scope anyway.
Now, is set nocount off necessary? No, as any new commands executed will be in a different scope, and by default set nocount off is always in effect. But as stated above in comments, it's considered a good practice, just to explicitly indicate that this setting will return to normal when the proc is finished executing.
I know this is a rather old post but it was the first hit on Google when I looked for the answer. The response above to test it was a very good idea.
I tested this out and wanted to update the above with some additional details.
The scope you create with a SET NOCOUNT ON flows to any procs which your procedure calls. So if your procedure does SET NOCOUNT ON and then you call a sproc, that sproc gets your SET NOCOUNT setting. The setting DOES go away when you exit your sproc but the setting flows down into called sprocs. If you SET NOCOUNT inside of the CALLED sproc, the outer sproc will have the SET NOCOUNT which it set and the inner sproc won't affect the outer sproc.
So I think you don't really need to reset it at the end of your sproc because your settings will never flow OUT of your sproc upwards; however, if your sproc depends on the setting, it should set it before it needs it because if it gets called from another sproc, it could have a different setting than you assume.
only if you dont want to see
(1 row(s) affected) // or n rows....
most of the time - when you debug
and you use print command - so you want to see pure text of your own... so thats a good practice.
edit
it does Not affect your query result (on or off - it doesn't matter.)- if thats what's your asking. ( thanks JNK).
its simple. you dont need it if another program is running your procedure.
Lets say my python code is calling an mssql procedure, then I don't need the affected row count on my app, so I "SHOULD" definitely put "set nocount on" in my code

NHibernate INSERT TO SQL Calculated field SET NOCOUNT

I need to surpress messages output from a SQL function. As in 1 row affected. I can't use SET NOCOUNT as it's invalid in a function.
Anyone know a way to do this?
Thanks.
EDIT
I was trying to limit the background information in an attemp to boil the problem down to it's essence. But I'll expand. I'm using MSSQL2005 and NHibernate to insert a record in to a SQL table. On the table I have a computed column that runs the function which is reporting back 1 row affected.
I didn't really want to edit the NHibernate part of the process but it may be unavoidable.
A function that returns "(1 row affected)" will be part of a bigger query in a batch. It makes no sense to have SET NOCOUNT ON in the function
You need to do this:
SET NOCOUNT ON;
SELECT * FROM MyUDFTVF();
Note a stored procedure is simply a wrapper for this
CREATE PROC Whatever
AS
SET NOCOUNT ON;
SELECT * FROM MyUDFTVF();
GO
SET NOCOUNT ON is normally needed to stop triggers etc breaking client code: why do you need it here?
The nocount setting is not available in functions.
Stored procedures allow you to set nocount. So converting the function to a stored procedure would solve the problem.
Otherwise, the calling code will have to set nocount. That shouldn't be hard, but might be tedious if the function is used in many places.
P.S. If you post the reason why suppressing the count messages is required, perhaps we can offer some more solutions.

What are the consequences of a blanket update of stored procedures to include SET NOCOUNT ON

We have introduced a new data access framework for calling SQL Stored procedures. When calling a stored procedure that returns a recordset, we've run into problems where that stored procedure also performs an update (insert/update/delete) of some sort:
Cannot change the ActiveConnection
property of a Recordset object which
has a Command object as its source.
The solution to this is to add 'SET NOCOUNT ON' to the top of the stored procedure. This works just fine, and, of course, it also has a touted performance enhancement.
We are recommending to developers that when they want to write code to call an existing stored procedure, they must also refactor the stored procedure itself to include SET NOCOUNT ON.
But, this got me into wondering, what would be the potential consequences/risks of performing a blanket update of all stored procedures to include SET NOCOUNT ON. Under what scenarios would this break an SPs functionality? (given that ##ROWCOUNT function is updated even when SET NOCOUNT is ON)
Help, as always, much appreciated.
I think the main danger would be if any of your existing processes look for and/or assume that the rowcount will be returned without explicitly querying the value of ##ROWCOUNT.
It's possible that somewhere in your code is a stored proc that gets executed, and the application waits for the return row value to know that it completed, in which case the app would hang indefinitely.

SET NOCOUNT OFF or RETURN ##ROWCOUNT?

I am creating a stored procedure in Sql Server 2008 database. I want to return the number of rows affected. Which is a better option SET NOCOUNT OFF or RETURN ##ROWCOUNT?
ALTER PROCEDURE [dbo].[MembersActivateAccount]
#MemberId uniqueidentifier
AS
BEGIN
-- Should I use this?
SET NOCOUNT OFF;
UPDATE [dbo].Members SET accountActive = 1 WHERE id = #MemberId;
--Or should I SET NOCOUNT ON and use the following line instead?
--return ##ROWCOUNT;
END
I know that both work, but which is a better choice and why?
After some trying I am coming to a conclusion that SET NOCOUNT is OFF by default inside stored procedures. Is it possible to change this behavior inside my database?
Use ##RowCount. It's explicit and transparent, it is entirely controlled by your code rather than a built-in behaviour.
The NOCOUNT option can be manually set to default to ON (Optons>Query Execution>SQL Server>Advanced). If you set it this way but then declare SET NOCOUNT OFF in your stored procedure then that local setting takes precedence.
Don't use RETURN for values. By convention RETURN from stored procedures is for error codes, 0 meaning no error and non-0 meaning some kind of problem. If you need data back, the appropriate way to do it is with an OUTPUT parameter. It's a little counter-intuitive based on other languages' use of return.
I know that having SET NOCOUNT ON would make a DataAdapter think there was a concurrency conflict.
You can read about it on MSDN. If the code is going to be used by DataAdapters then obviously don't use SET NOCOUNT ON.
It looks like SqlCommand also has this behaviour, which I guess is the reason why the DataAdapter has a problem (as under the hood it will use a Command object).
Reasons for using SET NOCOUNT ON/OFF:
To control the stack overflow while inserting rows into any table.
Passing the T-Sql messages while executing of the queries or nested queries.
To Show or viewing the latest queries executed.
To get information on the latest record escalation.
Why we use SET NOCOUNT on/off ---
Ans : we can understand this by following steps
step 1 : execute query "Select top 10 * from table name".
step 2 : open message window it shows a message "10 rows affected". it creates extra overheads and extends our execution time.
step 3 : to overcome this extra overheads we use SET NOCOUNT ON. If it is On then it will never count the number of row returns instead it sows a message commands completed successfully.
step 4 : By default NOCOUNT is ON then it counts the number of returned rows that is why my suggestion that it should off during creating new procedures to get better performance from database server.