Wednesday 25 February 2015

Understanding SQL Server Concurrency

When you can't get to your data because another application has it locked, a thorough knowledge of SQL Server concurrency will give you the confidence to decide what to do.
Download your free copy of SQL Server Concurrency: Locking, Blocking and Row Versioning, the new eBook by world-renowned SQL Server trainer Kalen Delaney, dive into SQL Server's models for concurrent access, and learn how to troubleshoot blocking, deadlocking, and update conflicts.
The simplest way to catch these problems on your servers is with SQL Monitor, so grab a free trial and see how quickly you can put Kalen's tips into practice.

1. Free eBook: SQL Server Concurrency: Locking, Blocking and Row Versioning

SQL Server Backup and Restore cover
  • Find out how to ensure you always have access to your data when you need it.
  • Learn about transaction isolation levels, ACID properties, and SQL Server's optimistic and pessimistic concurrency models.
  • Get hints and tips on how to troubleshoot excessive blocking and deadlocking.

2. Get instant alerts when blocking or deadlocking occurs

SQL Monitor box
  • Try SQL Monitor for free, and get alerts when blocking or deadlocking occurs.
  • Quickly see what the victim process is, so you know where changes need to be made.
  • Fix the problem fast with the troubleshooting hints in your free eBook.

http://www.red-gate.com/products/dba/sql-monitor/entrypage/sql-server-concurrency-ebook?utm_source=ssc&utm_medium=publink&utm_campaign=sqlmonitor&utm_content=concurrency_ebook&utm_term=sqlserverconcurrency

sql query website

when using an OUTER JOIN, you should put criteria on the outer table in the join condition, not in the WHERE clause

As this nice SQLTeam article explains, when using an OUTER JOIN, you should put criteria on the outer table in the join condition, not in the WHERE clause.  However, I often see a "workaround" to avoid this simple and solid rule, which might seem to work but actually doesn't.  Since it is hard to explain why over and over in forum posts, I thought it might be helpful to address that here once and for all with an example.  Confused? Stick with me, I promise this will make sense eventually.

Suppose we have the following tables:

create table Depts  (deptID int, DeptName varchar(20))
create table Emps (empID int, EmpName varchar(20), deptID int, salary money)

insert into Depts (deptID, deptName)
select 1, 'Dept A' union all
select 2, 'Dept B' union all
select 3, 'Dept C'

insert into Emps (empID, EmpName, DeptID, salary)
select 1, 'Emp 1', 1, 50 union all
select 2, 'Emp 2', 1, 75 union all
select 3, 'Emp 3', 2, 60 union all
select 3, 'Emp 4', 2, 45

Notice the following:
  • We have 3 departments
  • Each employee is assigned to a department
  • There are no employees assigned to 'Dept C'
Now, if we want to select all departments along with any employees that happen to be in that department, we use an OUTER JOIN since an INNER JOIN will only return departments with matching employees:

select d.deptID, d.DeptName, e.empID, e.empName, e.salary
from Depts d
left outer join
    Emps e on e.deptID = d.deptID

deptID      DeptName             empID       empName              salary

----------- -------------------- ----------- -------------------- ---------
1           Dept A               1           Emp 1                50.00
1           Dept A               2           Emp 2                75.00
2           Dept B               3           Emp 3                60.00
2           Dept B               3           Emp 4                45.00
3           Dept C               NULL        NULL                 NULL

(5 row(s) affected)


Ok, so far so good.  Now, what if we wish to return only employees with a salary of >50?  If we add the criteria to our WHERE clause (WHERE e.salary > 50) this means that the last row in the above result -- 'Dept C' --  will not be returned, since the salary column is null:

select d.deptID, d.DeptName, e.empID, e.empName, e.salary
from Depts d
left outer join
    Emps e on e.deptID = d.deptID
where
    e.salary > 50

deptID      DeptName             empID       empName              salary
----------- -------------------- ----------- -------------------- ---------------------
1           Dept A               2           Emp 2                75.00
2           Dept B               3           Emp 3                60.00

(2 row(s) affected)


Thus, as Mark's article explains quite well, you simply put that criteria directly into the JOIN condition and you get the results you need:

select d.deptID, d.DeptName, e.empID, e.empName, e.salary
from Depts d
left outer join
    Emps e on e.deptID = d.deptID and e.salary > 50

deptID      DeptName             empID       empName              salary
----------- -------------------- ----------- -------------------- ---------------------
1           Dept A               2           Emp 2                75.00
2           Dept B               3           Emp 3                60.00
3           Dept C               NULL        NULL                 NULL

(3 row(s) affected)

However, you might be tempted to look at your data and think that to return these results, instead of putting the criteria in the JOIN, you can simply handle that NULL situation in your WHERE clause like this:

select d.deptID, d.DeptName, e.empID, e.empName, e.salary
from Depts d
left outer join
    Emps e on e.deptID = d.deptID 
where
    e.salary > 50 or e.empID is null

deptID      DeptName             empID       empName              salary
----------- -------------------- ----------- -------------------- ---------------------
1           Dept A               2           Emp 2                75.00
2           Dept B               3           Emp 3                60.00
3           Dept C               NULL        NULL                 NULL

(3 row(s) affected)


That works, right?  The NULL results are returned, and we only have employees with a salary above 50.  Case closed!  This would seem to indicate that we can indeed reference our outer tables in our WHERE clause, we just have to make sure that we deal with the NULL's that come back so that we don't filter them out.

However, that does not work!  Why not?  Well, right now we have no employees in Dept C at all, but what if we add one, with a salary below $50?  Let's try it:

insert into Emps (empID, EmpName, deptID, salary) values(4, 'Emp 5', 3, 35)

select d.deptID, d.DeptName, e.empID, e.empName, e.salary
from Depts d
left outer join
    Emps e on e.deptID = d.deptID 
where
    e.salary > 50 or e.empID is null

deptID      DeptName             empID       empName              salary
----------- -------------------- ----------- -------------------- ---------------------
1           Dept A               2           Emp 2                75.00
2           Dept B               3           Emp 3                60.00

(2 row(s) affected)

What happened here?  Where did Dept C go?  Suddenly, our SQL statement no longer returns the desired results.  Why not?  Well, like pretty much all programming bugs, it's because that silly computer did exactly what you told it to do.  Let's look at our data again, without any WHERE clause at all:

select d.deptID, d.DeptName, e.empID, e.empName, e.salary
from Depts d
left outer join
    Emps e on e.deptID = d.deptID 

deptID      DeptName             empID       empName              salary
----------- -------------------- ----------- -------------------- ---------------------
1           Dept A               1           Emp 1                50.00
1           Dept A               2           Emp 2                75.00
2           Dept B               3           Emp 3                60.00
2           Dept B               3           Emp 4                45.00
3           Dept C               4           Emp 5                35.00

(5 row(s) affected)

Notice that we have no NULL values now, and there is at least 1 employee for each department.  Now, let's go through those results and manually apply our WHERE clause, row by row, removing all rows that don't meet the criteria:

where e.salary > 50 or e.empID is null

deptID      DeptName             empID       empName              salary
----------- -------------------- ----------- -------------------- ---------------------
1           Dept A               1           Emp 1                50.00
1           Dept A               2           Emp 2                75.00
2           Dept B               3           Emp 3                60.00
2           Dept B               3           Emp 4                45.00
3           Dept C               4           Emp 5                35.00


So, you can see now that your WHERE clause simply was not correctly written!  What condition, then, it is applying on our data?  Well, remember that, when using OUTER JOINS, the expression "outertable.primarykeycolumn is null" means "there is no matching row in the outer table meeting the join criteria".  Thus, our WHERE clause really reads:

"return all departments and employees with a salary > 50, or in which there are no employees at all."

So, don't try to use this "trick" to avoid putting criteria in your outer joins.   Of course, this also applies if you use ISNULL, CASE or COALESCE to handle the nulls in your WHERE clause -- the same (wrong) results will be returned.

 The rule is very simple and very easy to remember:

Never reference OUTER JOIN-ed tables in your WHERE clause.

The exception is when you want to test if your outer join expression matched any rows at all; i.e.,  checking to see if the outer table's primary key column is NULL.  Otherwise, put any criteria on your outer tables within the join expression itself.

. . .

Side note: To apply criteria to your outer tables, in addition to the JOIN clause, you could also use a derived table or CTE, like this:

select d.deptID, d.DeptName, e.empID, e.empName, e.salary
from Depts d
left outer join
    (select * from Emps where salary > 50) e on e.deptID = d.deptID 

deptID      DeptName             empID       empName              salary
----------- -------------------- ----------- -------------------- ---------------------
1           Dept A               2           Emp 2                75.00
2           Dept B               3           Emp 3                60.00
3           Dept C               NULL        NULL                 NULL

(3 row(s) affected)

...

Any questions or comments are welcome!  I hope this helps clear a few things up, and if you've ever used the "where ... or outertable.pk is null" technique in the past, you might want to double-check your code and your results, they may not be what you expect!

see also:

Tuesday 24 February 2015

interview Qus

http://www.programmerinterview.com/index.php/database-sql/advanced-sql-interview-questions-and-answers/


http://www.careerride.com/

Aggregate Function in LINQ


The following are the types of aggregate functions:
  1. Min
  2. Max
  3. Count
  4. Sum
  5. Average
  6. Aggregate
All these functions are present in the System.Linq namespace.

Let's look at an example of each function.

Example 1
In this example we will create a console application that will give us the smallest number from an array without using LINQ and we will write the same program using LINQ.

So, let's dive right in.

In Visual Studio, I have a console application in which there is a class Program with a Main method.

In the Main method I have created an array of numbers as in the following:

main method

From the preceding array we want to retrieve the smallest number and print it on the console window.

To print the lowest number, first we need to create a variable that will hold the value.

order to print

To store the lowest number in the LowestNumber variable, we need to find the smallest number from the ArrayOfNumbers and for that we can use a foreach loop.

foreach loop

We have used a foreach loop to retrieve all the numbers from the ArrayOfNumbers. After retrieving all the values, check if the nullable variable that we created does not have a value and using or(||) check if the value of n is smaller than the LowestNumber value, if any of the case is true then assign the value of n to the LowestNumber variable.

So, when the code executes, it will first check if the lowestNumber variable contains a value or not. If not then it will assign the first value of n to ArrayOfNumbers. Then again it will loop and check the same condition but now the first condition will be false because now the LowestNumber has a value. So, it will check the second condition and if the n value is smaller than the LowestNumber, then value of n will be assigned to the LowestNumber.
  1. using System;  
  2.   
  3. namespace AggregateFunctionsInLINQ {  
  4.    class Program {  
  5.       static void Main(string[] args) {  
  6.          int[] ArrayOfNumbers = { 5, 4, 6, 3, 7, 1, 3, 9 };  
  7.          int? LowestNumber = null;  
  8.   
  9.   
  10.          foreach(int n in ArrayOfNumbers) {  
  11.             if(!LowestNumber.HasValue || n < LowestNumber) {  
  12.                LowestNumber = n;  
  13.             }  
  14.          }  
  15.          Console.WriteLine(LowestNumber);  
  16.       }  
  17.    }  
  18. }  
Run the application

Run the application

To get the smallest number, we must write many lines of codes. Now let's see how to do the same thing using LINQ.

To get the smallest number, we can use the Min() aggregate function.

aggregate function

Look at the intellisense, this function returns the minimum value in a sequence. So, using this extension method we will get the lowest value from the ArrayOfNumbers.
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4.   
  5. namespace SmallestNumberUsingLINQ {  
  6.    class Program {  
  7.       static void Main(string[] args) {  
  8.          int[] ArrayOfNumbers = { 5, 4, 6, 3, 7, 1, 3, 9 };  
  9.          int LowestNumber = ArrayOfNumbers.Min();  
  10.          Console.WriteLine(LowestNumber);  
  11.       }  
  12.    }  
  13. }  
Run the application

Run

Example 2
Let's look at another example. In this we will retrieve the largest number from ArrayOfNumbers.

ArrayOfNumbers

In the preceding cs file, we have written the same code except we are checking if the n value is greater than the LargestNumber value. If the condition is true then we are assigning the n's value to the LargestNumber variable.

Run the application

application

Let's see how to do the same thing using LINQ.

To get the minimum value from the integer of arrays, we used the Min aggregate function. To get the maximum value from the integer of arrays, we will use the Max aggregate function.

Max aggregate function

Run the application

Run application

Let's say from the ArrayOfNumbers we want the largest even number.

Without LINQ

To get the largest even number, we need to add another condition where we will check if the number returns 0 as the remainder.

remainder

Run the application

largest even number

Using LINQ

To filter the records we can use the Where extension method.

Using LINQ

Run the application

Where

Example 3 

In this demo we will find the sum of all the numbers.

Without LINQ

Without LINQ

Run the application

sum of all the numbers

With LINQ

To get the sum of all the numbers, we can use Sum aggregate function.

With LINQ

Run the application

Sum aggregate function

Example 4 

In this example we will count the number elements present in ArrayOfNumbers.

Without LINQ

count the number

Run the application

present in ArrayOfNumbers

Using LINQ

number elements present

Run the application

output

Example 5

In this example we will see how to get the average of the ArrayOfNumbers.

Without LINQ

get the average

Run the application

cmd

With LINQ

To get the average in LINQ, we can use the Average aggregate function.

get the average in LINQ

Note: The return type of this function is double.

Run the application

return type of this function

Example 6 

In this demo we will see how to use the Aggregate function.

In my console application, I have this array of Names.
  1. string[] Names = {"Sam","Sara","Aiden","Trevor","Michael"};  
I want this separate string to be displayed as a single comma-separated string.

So. Let's see how do it.

Without LINQ

achieve it

Run the application

displayed

We got the output as a single string separated by comma.

But we have a comma after the last string and we don't want a comma after the last string.

So, let's see how to remove it.

To remove a comma from the last string, we can use the LastIndexOf method.

remove comma

Run the application

LastIndexOf method

With LINQ

string

Run the application
last string

You might be thinking, how does this Aggregate function work?

If you look at the expression string SingleString = Names.Aggregate((a, b) => a + ", " + b);

This (a, b) expression is nothing but two parameters of type string.

When the program first executes, It will take Sam and Sara and assign it to a and b and based on the expressiona + ", " + b this aggregate function will concatenate these two values separated by a comma and assign this value back to the first parameter, a.

Then it will take Aiden in b and will concatenate Sam, Sara and Aiden separated by commas because the parameter a holds the previous concatenated values and then again this a will hold all the three values and Trevor will be assigned to b and so on. In the end the final result will be assigned to the SingleString variable.