Showing posts with label direction. Show all posts
Showing posts with label direction. Show all posts

Tuesday, March 27, 2012

Advice on CASE statement

Can someone guide me in the correct direction as to what's going on with
this case statement:
This was derived from and access IIF statement
Access IIF statement:
IIf([meterreading] & ""="" Or [previousreading] & ""="",Null,
(IIf([MeterReading]>=[PreviousReading],[MeterReading]- [previousreading],[MeterReading]+([Rollo
ver]- [PreviousReading]))*IIf(IsNull([MultiFac
tor]),1,[MultiFactor]))+nz([UsageAdjustm
ent],0))
SQL Case statement:
select
case when 10000.0 is null or 1.0 is null
then null else case when 10000.0 >= 1.0 then (10000.0 - 1.0)
else 10000.0 + (4 - 1.0) end end * case when 22.0 is null
then 1 else 22.0 + isnull(4.0,0) end as CurUsage
Above is a sample of the case statement with the actual values instead of
the field names used in the actual statement so you may test. The result I
require and the result access renders using the exact values is 219982, but
the result I get from SQL is 259974. I believe that my case statement is
formatted incorrectly. If I simply compute all the value that would be
returned base on the case statement conditions I get the value I s.
select (10000.0 - 1.0) * 22.0 + isnull(4.0,0) = 219982
Any Ideas?
Best Regards,
Advice on Case StatementThe problem is that it will evaluate inside out. So the 22 + 4 is evaluated
prior to the multiplication.
I think just you just need to move your last END statement.
As in the following:
select
case when 10000.0 is null or 1.0 is null
then null else case when 10000.0 >= 1.0 then (10000.0 - 1.0)
else 10000.0 + (4 - 1.0) end end * case when 22.0 is null
then 1 else 22.0 end + isnull(4.0,0) as CurUsage
Ryan Powers
Clarity Consulting
http://www.claritycon.com
"Tim Harvey" wrote:

> Can someone guide me in the correct direction as to what's going on with
> this case statement:
> This was derived from and access IIF statement
> Access IIF statement:
> IIf([meterreading] & ""="" Or [previousreading] & ""="",Null,
> (IIf([MeterReading]>=[PreviousReading],[MeterReading]- [previousreading],[MeterReading]+([Rollo
ver]- [PreviousReading]))*IIf(IsNull([MultiFac
tor]),1,[MultiFactor]))+nz([UsageAdjustm
ent],0))
>
> SQL Case statement:
> select
> case when 10000.0 is null or 1.0 is null
> then null else case when 10000.0 >= 1.0 then (10000.0 - 1.0)
> else 10000.0 + (4 - 1.0) end end * case when 22.0 is null
> then 1 else 22.0 + isnull(4.0,0) end as CurUsage
> Above is a sample of the case statement with the actual values instead of
> the field names used in the actual statement so you may test. The result I
> require and the result access renders using the exact values is 219982, bu
t
> the result I get from SQL is 259974. I believe that my case statement is
> formatted incorrectly. If I simply compute all the value that would be
> returned base on the case statement conditions I get the value I s.
> select (10000.0 - 1.0) * 22.0 + isnull(4.0,0) = 219982
>
> Any Ideas?
>
> Best Regards,
> Advice on Case Statement
>
>|||1) First thing to learn is that ther is no CASE statement in SQL; there
is a CASE **expression**!! Important!! Expressions have a single data
type. Expressions have nothign to do with control flow; since SQL is a
declarative language, there is no concept whatsoever of control flow!!
This is basic programming concepts.
2) "CASE WHEN 10000.0 IS NULL OR .. " is absurd code; it is always
UNKNOWN. Do you understand the 3-Valued Logic in SQL?
3) Above is a sample of the case statement [sic] with the actual values
instead of the field [sic] names used in the actual statement so you may
test. <<
Columns are not anything like fields; please learn the foundations,
concepts and the right words. Now, how do you expect us to debug code
you will not show us? How do we tell the constants from the columns?
You failed to post even minimal DDL or a spec that makes sense. Try
again, if you really want help.
The CASE expression is an *expression* and not a control statement; that
is, it returns a value of one datatype. SQL-92 stole the idea and the
syntax from the ADA programming language. Here is the BNF for a <case
specification>:
<case specification> ::= <simple case> | <searched case>
<simple case> ::=
CASE <case operand>
<simple when clause>...
[<else clause>]
END
<searched case> ::=
CASE
<searched when clause>...
[<else clause>]
END
<simple when clause> ::= WHEN <when operand> THEN <result>
<searched when clause> ::= WHEN <search condition> THEN <result>
<else clause> ::= ELSE <result>
<case operand> ::= <value expression>
<when operand> ::= <value expression>
<result> ::= <result expression> | NULL
<result expression> ::= <value expression>
The searched CASE expression is probably the most used version of the
expression. The WHEN ... THEN ... clauses are executed in left to right
order. The first WHEN clause that tests TRUE returns the value given in
its THEN clause. And, yes, you can nest CASE expressions inside each
other. If no explicit ELSE clause is given for the CASE expression,
then the database will insert a default ELSE NULL clause. If you want
to return a NULL in a THEN clause, then you must use a CAST (NULL AS
<datatype> ) expression. I recommend always giving the ELSE clause, so
that you can change it later when you find something explicit to return.
The <simple case expression> is defined as a searched CASE expression in
which all the WHEN clauses are made into equality comparisons against
the <case operand>. For example
CASE iso_sex_code
WHEN 0 THEN 'Unknown'
WHEN 1 THEN 'Male'
WHEN 2 THEN 'Female'
WHEN 9 THEN 'N/A'
ELSE NULL END
could also be written as:
CASE
WHEN iso_sex_code = 0 THEN 'Unknown'
WHEN iso_sex_code = 1 THEN 'Male'
WHEN iso_sex_code = 2 THEN 'Female'
WHEN iso_sex_code = 9 THEN 'N/A'
ELSE NULL END
There is a gimmick in this definition, however. The expression
CASE foo
WHEN 1 THEN 'bar'
WHEN NULL THEN 'no bar'
END
becomes
CASE WHEN foo = 1 THEN 'bar'
WHEN foo = NULL THEN 'no_bar' -- error!
ELSE NULL END
The second WHEN clause is always UNKNOWN.
The SQL-92 Standard defines other functions in terms of the CASE
expression, which makes the language a bit more compact and easier to
implement. For example, the COALESCE () function can be defined for one
or two expressions by
1) COALESCE (<value exp #1> ) is equivalent to (<value exp #1> )
2) COALESCE (<value exp #1>, <value exp #2> ) is equivalent to
CASE WHEN <value exp #1> IS NOT NULL
THEN <value exp #1>
ELSE <value exp #2> END
then we can recursively define it for (n) expressions, where (n >= 3),
in the list by
COALESCE (<value exp #1>, <value exp #2>, . . ., n), as equivalent to:
CASE WHEN <value exp #1> IS NOT NULL
THEN <value exp #1>
ELSE COALESCE (<value exp #2>, . . ., n)
END
Likewise, NULLIF (<value exp #1>, <value exp #2> ) is equivalent to:
CASE WHEN <value exp #1> = <value exp #2>
THEN NULL
ELSE <value exp #1> END
It is important to be sure that you have a THEN or ELSE clause with a
datatype that the compiler can find to determine the highest datatype
for the expression.
A trick in the WHERE clause is use it for a complex predicate with
material implications.
WHERE CASE
WHEN <search condition #1>
THEN 1
WHEN <search condition #2>
THEN 1
..
ELSE 0 END = 1
Gert-Jan Strik posted some exampels of how ISNULL() and COALESCE() on
2004 Aug 19
CREATE TABLE #t(a CHAR(1));
INSERT INTO #t VALUES (NULL);
SELECT ISNULL(a,'abc') FROM #t;
SELECT COALESCE(a, 'abc') FROM #t;
DROP TABLE #t;
He always use COALESCE, with the exception of the following type of
situation, because of its performance consequences:
SELECT ...,
ISNULL((SELECT COUNT(*) -- or other aggregate
FROM B
WHERE B.key = A.key), 0)
FROM A;
Likewise, Alejandro Mesa cam up with this example:
SELECT 13 / COALESCE(CAST(NULL AS INTEGER), 2.00); -- promote to highest
type (decimal)
SELECT 13 / ISNULL(CAST(NULL AS INTEGER), 2.00); -- promote to first
type (integer)
--CELKO--
Please post DDL in a human-readable format and not a machine-generated
one. This way people do not have to guess what the keys, constraints,
DRI, datatypes, etc. in your schema are. Sample data is also a good
idea, along with clear specifications.
*** Sent via Developersdex http://www.examnotes.net ***

Advice on automating a job.

Hi I'm just looking for a little bit of advice to point me in the right direction before I start to put this together.

The task I have is too automate the clear down of the transaction logs. Presently I am manually going in and using this method:

BACKUP LOG {database name} WITH TRUNCATE_ONLY
DBCC SHRINKFILE ( {log file name},2 )

However now we have decided this would be best to be automated and I'm faily new to SQL server so I'm not sure the best way to go about this. So I was hoping someone could point me in the right direction that I go about doing it so I don't go off on a complete tangent. Ow and Can anyone think of any problem automating this job could cause.

My eternal graitude, EdWhy are you backing up with TRUNCATE ONLY? This does not give you any recoverability for transactions occuring after the last backup. If you really don't need point-in-time recoverability then you could just put the database in simple recovery mode.

blindman|||Ahh I see

I was trying to come up with a way of reducing the size transaction Log without, stopping the database and restarting and I came across this advice, I used the first statment because otherwise the the transactionlog won't shrink much. I didn't really consider the point that (I said I was new too this) this basically mean that the it is no longer actuly producing a functional backup.

Ouch

Well in that case I need to come up with a solution, Do you have any Idea what the best time to clear down the transaction logs would be? erm could I run this immediately before the back up. but then if the backup is faulty we would lose a whole days work and if I run it just after the backup then the next days would be useless, unless I run it immediately and make sure their is no transaction inbetween the backup and the transaction shrinking!

Do you know how to restore the transaction log to it orginal functioning glory!

Thanks Again Ed

Monday, March 19, 2012

Advanced SQL - Group By With Cube

Need some direction on getting these example results:

I need to group by 2-3 different attributes, one of them a calculated value off of a birthdate attribute, but I want to know whether they are over or under a certain age. I don't want to restrict the result set by age, but rather subgroup results by age ranges.

Simplified Ex:
SELECT class, time, count(nameID) as Total
from students
group by class, time
with cube

Ex RS:
class time >15 Total
-- -- -- --
Math 9:30 true 17
Math 9:30 false 8
PE 7:45 true 5
PE 7:45 false 10

Hopefully you get the idea. I can not figure out how to get the evaluated boolean of whether or not thier age is >15.

It is important that result set be a cube to calculate all the total and subgroup totals. I don't even know if this is possible in my case though.

All help greatly appreciated.

SlezakFirst, assuming you are using SQL Server 2000, you need to create a UDF which will calculate the age. You can find one here: http://www.databasejournal.com/img/UDF_GetAge.sql

Next, you can make use of this function in your query:


SELECT class, time, CASE WHEN dbo.GetAge(DateOfBirth,GETDATE()) > 15 THEN 'True' ELSE 'False' END AS '>15', count(nameID) as Total
from students
group by class, time, dbo.GetAge(DateOfBirth,GETDATE())
with cube

Terri|||That was pretty much what I wanted. Thank you greatly!

I did want to group by 'CASE WHEN dbo.GetAge(DateOfBirth,GETDATE()) > 15 THEN 'True' ELSE 'False' END' and not by 'dbo.GetAge(DateOfBirth,GETDATE())', but I was able to figure that out. :p

Much obliged, and I appreciate that GetAge function too.

Slezak

Friday, February 24, 2012

ADO.NET 2.0 Slows SP Execution By Large Factor

I'm hoping someone will be able to point me in the right direction for solving this problem as i've come a bit stuck.

The Sql Server 2005 Stored Procedure runs in about 3 secs for a small table when run from SQL Management Studio (starting withdbcc freeproccache before execution) but times out when run through ADO.NET on .NET (45 sec timeout).

I've made sure the connection was closed prior to opening and executing the adapter. I'm a bit stuck as where to check next though.

Any ideas greatfully received, Thanks

Can you give us something more to go on? If the stored procedure text is relatively short, can you post it with related tables/indexes and such?

|||

Could you please make sure that you are connected to the Sql Server before making call to that stored procedure... Just try to execute a small query with a top clause.

The problem seems with Connection

|||

Unfortunately the SP is fairly complicated at about 200 lines in all. In summary it comprises of two joins. One is a highly indexed Account table and the other is a YearToDate table.

The output is basically a list of regions and all the Revenue that they've generated over period X to Y.

Here's my data tier code. The bottleneck seems to be the last line as that is the part that takes ages when i'm stepping through in debug mode

ssCommand.CommandType =CommandType.StoredProcedure;
ssCommand.CommandText = "my_stored_proc";
ssCommand.Connection =newSqlConnection("my_con_str");
ssCommand.CommandTimeout = 45;
foreach (SqlParameter ssParamin mySqlParmCollection){
ssCommand.Parameters.Add(ssParam);
}
ssCommand.Connection.Open();
ssDataAdapter =newSqlDataAdapter(ssCommand);
ssDataAdapter.Fill(ssDataSet, sDataTableName);

Many thanks,

|||

The nice thing would be to check the Sql Profiler... By this way you will be able to know whether its hitting the Sql Server or not.. and it will narrow down the problem. Then you can see why its taking so long

|||

I've just done a trace and the execution took almost 45 secs to complete using ADO.NET

I then ran it through query analyser and it took 3 secs.

I'm very puzzled by all of this, I could understand the execution plans not being used though .NET but they were cleared whilst executing them using sql management..

Your help is much appreciated,

Matt

|||

This is a excerpt from one of the msdn forum ..

I had the same problem. Seems like the SQL execution plan was corrupted for the stored procedure. I created a new SP and and copied the code to the new SP from the old and ran the application and the data was returned in no time. This proves that this was a SQL server issue and probably the execution plan for the SP was not efficient when it is run from ADO.NET. The reason that the SP worked from the query analyser and not the application using ADO.NET is QA directly executes the SP on the server but ADO.NET internally executes the sp by calling sp_executesql. The dropping and recreating the SP from the database should be a quick fix for the future. It may be worth while to find out WHY this condition happens after a while on the database.

Here are some information from the research I did on this for your reference:
1) "SqlCommand.ExecuteReader executes all commands in the context of the sp_executesql stored procedure." (http://msdn2.microsoft.com/en-us/library/aa720629(VS.71).aspx)
2) "Stored procedure will recompile if there is a sufficient number of rows in a table referenced by the stored procedure has changed. SQL Server will recompile the stored procedure to be sure that the execution plan has the up-to-date statistics for the table. You will notice this problem quite often when you are working with temporary tables in SQL Server 7.0 as SQL Server will determine that after 6 modifications to a temporary table any stored procedure referencing that table will need to be recompiled."
(http://www.sql-server-performance.com/rd_optimizing_sp_recompiles.asp)
3) "You may have heard about a system stored procedure called sp_executesql. It lets you evaluate dynamic SQL, but it happens to also cache its execution plan."
(http://sqlblog.com/blogs/adam_machanic/archive/2006/07/12/controlling-stored-procedure-caching-with-dyanmic-sql.aspx)
4) "The WITH RECOMPILE option prevents reusing the stored procedure execution plan, so SQL Server does not cache a plan for this procedure and the procedure is always recompiled at run time. Using the WITH RECOMPILE option can boost performance if your query will vary each time it is run from the stored procedure, because in this case the wrong execution plan will not be used. "
(http://www.databasejournal.com/features/mssql/article.php/1565961)

Check the link

http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=1102019&SiteID=1

and try the solutions mentioned


Sunday, February 19, 2012

ADO in C ?

Hi. Can someone please point me in the direction of using ADO from C?

Thanks!

All sorts of tutorials here. http://www.functionx.com/