I have been researching for 3 days and trying different things but nothing
has worked so far. Any suggestions would be greatly appreciated.
Razvan
PS. It is useless to set any option at the end of a procedure, since
the option will be reset to the value it had when the procedure was
started, anyway.
There is all reason to run with ANSI_WARNINGS ON, as there are features
in SQL Server that requires this setting to be on. It also has the good
effect that with this setting in effect errors like overflow and
division by zero does not go unnoticed.
I don't know exactly what incorrect recordsets you get. My impression
is that the noise message about NULL in aggregates being ignored is
just dropped on the floor by ADO. But it may be a good idea to have
SET NOCOUNT ON everywhere.
--
Erland Sommarskog, SQL Server MVP, esq...@sommarskog.se
Books Online for SQL Server 2005 at
http://www.microsoft.com/technet/prodtechnol/sql/2005/downloads/books.mspx
Books Online for SQL Server 2000 at
http://www.microsoft.com/sql/prodinfo/previousversions/books.mspx
In the future, I will recommend writing all of our queries differently to
protect against null values but for now what can I do? Where can I set ansi
warnings off so they stay off?
The last statement is not the cause of the problem. The warning is
caused by some previous statement and this makes ADO to generate an
empty recordset for each message/resultset returned by the SP. To get
to your real recordset, you should execute:
Do While rcs.State = adStateClosed
Set rcs = rcs.NextRecordset
If rcs Is Nothing Then Exit Do
Loop
Usually, the warning is "Warning: Null value is eliminated by an
aggregate or other SET operation.". This is caused by an aggregate
function (for example: MIN, MAX, SUM, AVG, COUNT) called with an
expression which contains NULL values. For example, consider the
following query in Northwind:
SELECT AVG(DATEDIFF(d,OrderDate,ShippedDate)) FROM Orders
To avoid the warning, the query can be rewritten as:
SELECT AVG(DATEDIFF(d,OrderDate,ShippedDate)) FROM Orders
WHERE ShippedDate IS NOT NULL
Razvan
Yes; and what is your point? You are probably getting wrong answers,
destroying data integrity and your results will not port to DW or
other systems.
What is the cost of all that failure? If you worked for a drug
company and found that a recall would require literally hundreds of
bottles od drugs to be replaced, would you do it or not?
>> In the future, I will recommend writing all of our queries differently to protect against null values but for now what can I do? <<
Recommend it now, start working or it will not get done. There is
nothing more permanent than a kludge that can squeeze us by until
someone else has to maintain the mess.
I would start with your DDL to see if you have too many NULL-able
columns. Your data dictionary should explain the semanatics of each
NULL in the columns that require NULLs, so you can start there (ahhh..
you do have a data dictionary, don't you?).
Then start adding CHECK() constraints to prevent division by zero,
garbage in strings, etc.
After the DDL is clean, then go to the DML and look for generated
NULLs and other problems. My expereience is that fixing the DDL is
80% or more of the battle.
I'm not sure why setting ANSI Warnings off at the database level is a bad
thing. Our application is not using indexed views, computed columns or
heterogenous queries. Most of our aggregate functions are min and max dates
for which nulls do not cause irregular or incorrect results.
In response to Celko's recommendations, I am a developer not a DBA, so much
of what you say, although it makes sense, is outside my domain. I will
certainly keep your suggestions in mind for future projects but I don't
believe our data has been compromised to the degree you suggest.
Did you try using SET NOCOUNT ON?
> I'm not sure why setting ANSI Warnings off at the database level is a bad
> thing. Our application is not using indexed views, computed columns or
> heterogenous queries.
Not today, but maybe tomorrow.
Out of legacy we run our application with SET ANSI_WARNINGS OFF. This
has more than once been detrimental as division-by-zero and overflow
errors have gone unnoticed, causing more serious problems along the
road.
I really do understand what you all are saying. I have an app scheduled to
go in next week and it's causing problems for the source system my app
depends on. The recompiles are killing us. It really isn't feasible at this
time to change the way we've been doing things for the last 5 years. It's
possible someone will have time to rewrite all of these to be compliant with
standards, but this would require a complete retesting of 2 applications, not
something we have the resources for right now. Like I said before, we are not
doing any mathematical calculations in this app, not even avg. Min and Max
for dates is about it.
I do appreciate the time you all have devoted to my question. I am at my
wit's end.
My initial question has never been answered, but this may be as close as I
get.
cn.Execute "SET ANSI_WARNINGS OFF"
This setting should remain in effect for that connection (until a
different SET ANSI_WARNINGS is encountered or until the connection is
closed). However, if you execute any SET option in a stored procedure,
it will remain in effect only for the duration of that SP (and of
other SP-s called by it) and it will revert to the previous value of
that option when the SP ends.
Razvan
Thank you so much Razvan, I'm almost there!
Well, then change it to open a connection first, execute SET
ANSI_WARNINGS, then open the recordset with the connection object
instead of the connection string.
Razvan