Friday, 18 November 2011

SSIS Package stored procedure


ALTER PROC [dbo].[InsertInto_BGCMAddress]   
            @BCE_Address_ID varchar(100)   
           ,@Address_Line_1 varchar(100)   
           ,@City varchar(50)   
           ,@State_Province varchar(100)   
           ,@Postal_Area varchar(100)   
           ,@Country varchar(100)   
           ,@Phone_Number varchar(100)
   
AS BEGIN   
   
DECLARE @BGCM_ID INT ,@COUNT INT
 SELECT @BGCM_ID = isnull(BGCM_ID,0) FROM PMP_BGCMCustomer WHERE BCE_ID=@BCE_Address_ID  and Customer_Type <> 'Physician'
 IF(@BGCM_ID <> 0)
  BEGIN
       INSERT INTO PMP_BGCMAddress   
       ([BGCM_ID]   
       ,[BCE_Address_ID]   
       ,[Last_Modified_Date]   
       ,[Last_Modified_Source]   
       ,[Address_Line_1]   
       ,[City]   
       ,[State_Province]   
       ,[Postal_Area]   
       ,[Country]   
       ,[Phone_Number]   
       ,[Create_Date]   
       ,[Address_Status_Code])   
    VALUES   
       (@BGCM_ID   
       ,@BCE_Address_ID   
       ,getdate()   
       ,'CE'   
       ,@Address_Line_1   
       ,@City   
       ,@State_Province   
       ,@Postal_Area   
       ,@Country   
       ,@Phone_Number   
       ,getdate()   
       ,'Active')
      
 END
END

--------------------------------------------------------------------------------------------------------------------

ALTER PROC [dbo].[InsertInto_BGCMAffiliation]
     @From_BGCM_ID as VARCHAR(100),
           @To_BGCM_ID as VARCHAR(100),
           @Last_Modified_Date as datetime,
           --@Last_Modified_Source as VARCHAR(100),
           @Create_Date as datetime
           --@Affiliation_Status_Code varchar(100)
AS BEGIN
Declare @FBGCM_ID as VARCHAR(100),@TBGCM_ID as VARCHAR(100),@From_BGCM_ID_Exist as VARCHAR(100),@To_BGCM_ID_Exist as VARCHAR(100)

SELECT @FBGCM_ID = BGCM_ID FROM PMP_BGCMCustomer
WHERE BCE_ID = @From_BGCM_ID AND Customer_Type = 'Physician'

SELECT  @TBGCM_ID = BGCM_ID FROM PMP_BGCMCustomer
WHERE BCE_ID  = @To_BGCM_ID AND Customer_Type <> 'Physician'
IF(@FBGCM_ID <> null and @TBGCM_ID <> null)
BEGIN
Select @From_BGCM_ID_Exist = From_BGCM_ID from PMP_BGCMAffiliation where From_BGCM_ID = @FBGCM_ID
Select @To_BGCM_ID_Exist = To_BGCM_ID from PMP_BGCMAffiliation where To_BGCM_ID = @TBGCM_ID
IF (@From_BGCM_ID_Exist <> null AND  @To_BGCM_ID_Exist <> null)
BEGIN
UPDATE PMP_BGCMAffiliation SET
 Last_Modified_Date = @Last_Modified_Date,
 Last_Modified_Source = 'CE',
 Create_Date = @Create_Date,
 Affiliation_Status_Code = 'Active' where From_BGCM_ID = @FBGCM_ID AND To_BGCM_ID  = @TBGCM_ID
END
ELSE
BEGIN
INSERT INTO PMP_BGCMAffiliation
(From_BGCM_ID,To_BGCM_ID,Last_Modified_Date,Last_Modified_Source,Create_Date,Affiliation_Status_Code)
    VALUES
(@FBGCM_ID,@TBGCM_ID,@Last_Modified_Date,'CE',@Create_Date,'Active')
END
END
END
----------------------------------------------------------------------------------
ALTER PROC [dbo].[InsertInto_BGCMStateLicense]     
     
 @BCE_State_License_ID varchar(100),     
 @State_License_State varchar(100),     
 @State_License_Number varchar(100),     
 @State_License_Expiration_Date varchar(100) , 
 @MA_Recipient_ID varchar(100)    
     
AS BEGIN     
 DECLARE @BGCM_ID INT
      
 SELECT @BGCM_ID = BGCM_ID FROM PMP_BGCMCustomer WHERE BCE_ID=@BCE_State_License_ID   
   
 IF(@BGCM_ID <>'' )
 BEGIN
 Declare @BCE_State_License_ID_exist as varchar(100)

 select @BCE_State_License_ID_exist = BCE_State_License_ID from PMP_BGCMStateLicense where BGCM_State_License_ID = @BCE_State_License_ID_exist

  IF(@BCE_State_License_ID_exist > 0)
  BEGIN
  UPDATE PMP_BGCMStateLicense SET [BGCM_ID] =@BGCM_ID,
       [Last_Modified_Date] =GETDATE(),
       [Last_Modified_Source]= 'CE',
       [State_License_Status]= 'Active',
       [State_License_State]=@State_License_State,
       [State_License_Number]=@State_License_Number,
       [State_License_Expiration_Date]=@State_License_Expiration_Date,
       MA_Recipient_ID = @MA_Recipient_ID
       WHERE [BCE_State_License_ID] =@BCE_State_License_ID
  END
  ELSE
  BEGIN 
 
     INSERT INTO PMP_BGCMStateLicense     
       ([BGCM_ID]     
       ,[BCE_State_License_ID]     
       ,[Last_Modified_Date]     
       ,[Last_Modified_Source]     
       ,[State_License_Status]     
       ,[State_License_State]     
       ,[State_License_Number]     
       ,[State_License_Expiration_Date],MA_Recipient_ID)     
     VALUES     
       (@BGCM_ID     
       ,@BCE_State_License_ID     
       ,GETDATE()     
       ,'CE'     
       ,'Active'     
       ,@State_License_State     
       ,@State_License_Number     
       ,@State_License_Expiration_Date,@MA_Recipient_ID)
  END     
   END      
END 

----------------------------------------------------------------------------------------

ALTER PROC [dbo].[InsertInto_ContactBGCMAddress]     
   @BCE_Address_ID varchar(100)     
     ,@Address_Line_1 varchar(100)     
     ,@City varchar(50)     
     ,@State_Province varchar(100)     
     ,@Postal_Area varchar(100)     
     ,@Country varchar(100)     
     ,@Phone_Number varchar(100)  
AS
BEGIN   
 Begin tran insertContact
  DECLARE @BGCM_ID INT, @BiometContactId VARCHAR(100),@COUNT INT  
  Declare curContact Cursor
  For 
  select From_BGCM_ID from PMP_BGCMAffiliation where To_BGCM_ID =  @BCE_Address_ID               
  open  curContact
  Fetch next from curContact into @BiometContactId
  While @@FETCH_STATUS = 0
  Begin

   SELECT @BGCM_ID = BGCM_ID FROM PMP_BGCMCustomer WHERE BCE_ID= @BiometContactId  and Customer_Type = 'Physician'
   IF (EXISTS(select BGCM_ID from PMP_BGCMAddress where BGCM_ID = @BGCM_ID))
BEGIN
 
   --update PMP_BGCMAddress set
   --BCE_Address_ID = @BCE_Address_ID,
   --Last_Modified_Date = getdate(),   
   --Last_Modified_Source = 'CE',
   --Address_Line_1 = @Address_Line_1,
   --City = @City,
   --State_Province = @State_Province,
   --Postal_Area = @Postal_Area,
   --Country = @Country,
   --Phone_Number = @Phone_Number,
   --Create_Date = getdate(),
   --Address_Status_Code = 'Active'
   --where BGCM_ID = @BGCM_ID
    SET @COUNT = 1
 
END
   ELSE
BEGIN
   INSERT INTO PMP_BGCMAddress     
     ([BGCM_ID]     
     ,[BCE_Address_ID]     
     ,[Last_Modified_Date]     
     ,[Last_Modified_Source]     
     ,[Address_Line_1]     
     ,[City]     
     ,[State_Province]     
     ,[Postal_Area]     
     ,[Country]     
     ,[Phone_Number]     
     ,[Create_Date]     
     ,[Address_Status_Code])     
   VALUES     
     (@BGCM_ID     
     ,@BCE_Address_ID     
     ,getdate()     
     ,'CE'     
     ,@Address_Line_1     
     ,@City     
     ,@State_Province     
     ,@Postal_Area     
     ,@Country     
     ,@Phone_Number     
     ,getdate()     
     ,'Active')
   
END
 
   Fetch next from curContact into @BiometContactId
End
  close curContact
  DEALLOCATE curContact
 Commit tran insertContact
End

-----------------------------------------------------------------------------------------------------------






Monday, 7 November 2011

sort the column Table_Description asc order except on field


/*     Alphabetize all products in the list    */
/*
SELECT ROW_NUMBER() OVER (  ORDER BY Table_Description ) AS RowNumber, *
into temp_table
FROM PMP_ListManagement

select * from temp_table


UPDATE PMP_ListManagement
SET Display_order = RowNumber
FROM PMP_ListManagement T
INNER JOIN temp_table CT
ON T.Table_Id = CT.Table_Id

drop table temp_table
*/

--After update table for particular value set top which u didnt want to update
update PMP_ListManagement set Display_Order = 0 where Display_Order = 'No Product'

---Now display records on asc order
select * from PMP_ListManagement order by Display_Order

Wednesday, 2 November 2011

Email Demo (simple email sending application)

----------------------copy code and paste it to Default.aspx page-------------------


  <%@ Page Language="C#" AutoEventWireup="true"  CodeFile="Default.aspx.cs" Inherits="_Default" %>
 
  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">

  <html xmlns="http://www.w3.org/1999/xhtml" >
  <head id="Head1" runat="server">
       <title>Send Email by .Net 2.0</title>
</head>
  <body>
      <form id="form1" runat="server">
       <div>
          <h2 style="background-color:Brown; color:Wheat; font-family:Verdana; font-size:14px" align=center>Please enter the following requested
                   information below to send us your comments.</h2>
               <table align=center>
                   <tr>
                       <td><span style="font-family:Verdana; font-size:12px; font-weight:bold;color:Brown;">Your Name:</span></td>
                       <td><asp:textbox id="txtName" Width="241" Runat="server"></asp:textbox></td>
                   </tr>
                   <tr>
                       <td><span style="font-family:Verdana; font-size:12px; font-weight:bold;color:Brown;">Your Email Address:</span></td>
                      <td><asp:textbox id="txtEmail" Width="241" Runat="server"></asp:textbox></td>
                   </tr>
                   <tr>
                       <td colSpan="2" ><span style="font-family:Verdana; font-size:12px; font-weight:bold; color:Brown;">Your Comment:</span></td>
                   </tr>
                   <tr>
                       <td align="center" colSpan="2" width=100%><asp:textbox id="txtMessage" Width="100%" Runat="server" Height="99" TextMode="MultiLine" MaxLength="400"></asp:textbox></td>
                   </tr>
                   <tr>
                      <td colSpan="2"> </td>
                   </tr>
                   <tr>
                       <td align=center><asp:button id="btnSendmail" Runat="server" Text="Send Mail" OnClick="btnSendmail_Click"></asp:button></td>
                     <td align=center><asp:button id="btnReset" Runat="server" Text="Reset" OnClick="btnReset_Click"></asp:button></td>
                  </tr>
                   <tr>
                       <td colSpan="2"><asp:label id="lblStatus" Runat="server" EnableViewState="False"></asp:label></td>
                  </tr>
               </table>
      </div>
       </form>
   </body>
   </html>



------------------Cody code below and past it 2 Default.aspx.cs page-----------------------
  using System;
   using System.Configuration;
    using System.Web;
    using System.Web.Security;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Web.UI.HtmlControls;
    using System.Net.Mail;
   
   public partial class _Default : System.Web.UI.Page
  {
       #region  "Send email"
       protected void btnSendmail_Click(object sender, EventArgs e)
       {
          // System.Web.Mail.SmtpMail.SmtpServer is obsolete in 2.0
           // System.Net.Mail.SmtpClient is the alternate class for this in 2.0
           SmtpClient smtpClient = new SmtpClient();
          MailMessage message = new MailMessage();
 
          try
           {
               MailAddress fromAddress = new MailAddress(txtEmail.Text, txtName.Text);
  
               // You can specify the host name or ipaddress of your server
               // Default in IIS will be localhost
               smtpClient.Host = "exch001";
  
               //Default port will be 25
               smtpClient.Port = 25;
  
               //From address will be given as a MailAddress Object
               message.From = fromAddress;
  
               // To address collection of MailAddress
               message.To.Add("swapnil.mahanagre@annetsite.com");
               message.Subject = "Feedback";
  
               // CC and BCC optional
               // MailAddressCollection class is used to send the email to various users
               // You can specify Address as new MailAddress("admin1@yoursite.com")
               //message.CC.Add("admin1@yoursite.com");
               //message.CC.Add("admin2@yoursite.com");
  
               // You can specify Address directly as string
             //  message.Bcc.Add(new MailAddress("admin3@yoursite.com"));
             //message.Bcc.Add(new MailAddress("admin4@yoursite.com"));
               //Body can be Html or text format
               //Specify true if it  is html message
               message.IsBodyHtml = false;
  
               // Message body content
               message.Body = txtMessage.Text;
           
               // Send SMTP mail
               smtpClient.Send(message);
  
               lblStatus.Text = "Email successfully sent.";
           }
           catch (Exception ex)
           {
               lblStatus.Text = "Send Email Failed.<br>" + ex.Message;
           }
       }
       #endregion
  
       #region "Reset"
       protected void btnReset_Click(object sender, EventArgs e)
       {
           txtName.Text = "";
           txtMessage.Text = "";
           txtEmail.Text = "";
       }
       #endregion
   }

Tuesday, 1 November 2011

Find Missing Date Ranges in SQL

The Task Defined.
Imagine this: The customer runs the application that you've designed, and cannot see any sign of business transactions over a time period where he'd expect to see them. Your manager asks you to investigate. He will almost certainly ask you to find all of the missing days or hours in a date range where no data has been recorded: The date range can be several years.
The situation may become even worse; missing data can have unpleasant consequences, and that fact will make both the customer and the boss very nervous.
As a result, you will be under stress: you have to reassure your boss and the customer, and you need to do that in a very limited amount of time.
In this article, we will discuss a few SQL, one-query techniques that can help you to find the missing dates.
Preparations
Firstly, you will need to create and load an auxiliary table that will store the sequence of whole numbers. The volume of numbers in that table will be equal to the number of days in the year 2007 (see Listing1):

Listing 1- Create and load an auxiliary table
SET NOCOUNT ON;
DECLARE @startDate smalldatetime, @endDate smalldatetime
SELECT @startDate = 'Jan 01, 2007',
       @endDate = DATEADD(yy, 1, @startDate);

IF EXISTS(SELECT * FROM sysobjects
   WHERE ID = (OBJECT_ID('sequence')) AND xtype = 'U')
DROP TABLE sequence;
CREATE TABLE sequence(num INT NOT NULL PRIMARY KEY);

WITH numbers AS
(
 SELECT 1 AS num
 UNION ALL
 SELECT num + 1 FROM numbers
     WHERE num < (SELECT DATEDIFF(dd, @startDate, @endDate))
)
INSERT INTO sequence
SELECT num FROM numbers
OPTION (MAXRECURSION 0);


-----------------------------
Secondly, generate some test data and load that data into a sample table. Then produce the gaps, using the next algorithm: delete dates, where the number of days since Jan 01, 1900, divided by 4 or 5 or 6 has zero in remainder.
The second preparation step can be done this way (see Listing2):
Listing2. Create and load a sample table

DECLARE    @iniDate datetime;
SELECT @iniDate = 'Dec 31, 2006';
IF EXISTS(SELECT * FROM sysobjects
   WHERE ID = (OBJECT_ID('sampleDates')) AND xtype = 'U')
DROP TABLE sampleDates;
CREATE TABLE sampleDates(theDate smalldatetime PRIMARY KEY)
INSERT INTO sampleDates
SELECT DATEADD(dd, num, @iniDate) theDate
   FROM sequence;

-- Create gaps
DELETE sampleDates
   WHERE DATEDIFF(dd, 0, theDate)%3 = 0
   OR DATEDIFF(dd, 0, theDate)%4 = 0
   OR DATEDIFF(dd, 0, theDate)%5 = 0;
SELECT * FROM sampleDates;

Results:

theDate
-----------------------
2007-01-02 00:00:00.000
2007-01-03 00:00:00.000
2007-01-06 00:00:00.000
2007-01-09 00:00:00.000
. . . . . . . . . . . .
2007-12-20 00:00:00.000
2007-12-23 00:00:00.000
2007-12-25 00:00:00.000
2007-12-28 00:00:00.000
2007-12-29 00:00:00.000

(146 row(s) affected)
--------------------------------------------
Now that we have the auxiliary table and the sample data, we can try out a few techniques.
Technique #1 –The simple list
The first technique is quite common and uses an outer join (see Listing3):
Listing3. Common solution


-- The solution, where missing days are represented by NULLs
SELECT theDate
   FROM sequence t1 LEFT OUTER JOIN sampleDates t2
   ON DATEADD(dd, t1.num, 'Dec 31, 2006') = t2.theDate;

Results:

theDate
-----------------------
NULL
2007-01-02 00:00:00.000
2007-01-03 00:00:00.000
NULL
NULL
2007-01-06 00:00:00.000
NULL
NULL
2007-01-09 00:00:00.000
. . . . . . . . . . . .

2007-12-20 00:00:00.000
NULL
NULL
2007-12-23 00:00:00.000
NULL
2007-12-25 00:00:00.000
NULL
NULL
2007-12-28 00:00:00.000
2007-12-29 00:00:00.000
NULL
NULL

(365 row(s) affected)

-- The solution that shows only missing days
SELECT DATEADD(dd, num, 'Dec 31, 2006') missingDate
   FROM sequence t1 LEFT OUTER JOIN sampleDates t2
   ON DATEADD(dd, t1.num, 'Dec 31, 2006') = t2.theDate
   WHERE t2.theDate IS NULL;

Results:

missingDate
-----------------------
2007-01-01 00:00:00.000
2007-01-04 00:00:00.000
2007-01-05 00:00:00.000
2007-01-07 00:00:00.000
2007-01-08 00:00:00.000
2007-01-10 00:00:00.000
. . . . . . . . . . . .
2007-12-21 00:00:00.000
2007-12-22 00:00:00.000
2007-12-24 00:00:00.000
2007-12-26 00:00:00.000
2007-12-27 00:00:00.000
2007-12-30 00:00:00.000
2007-12-31 00:00:00.000

(219 row(s) affected)

--------------------------------------------------------------
There is nothing wrong with the solutions shown in the Listing3. However, if you need to find the missing hours in the whole year or the missing days in a few years, these queries may produce a long list of dates, which would be soon become unwieldy and difficult to interpret.
Your manager would not appreciate being given this sort of report.
Therefore, you need to find another solution, which will represent the result in a way that is more convenient for reading and analyzing.
Technique #2 –finding the ranges
Think of the missing dates as being a number of gaps in the continuous sequence of the dates. Then, instead of generating each missing date, you can show just the beginning and the end of each gap. The code in the Listing4 demonstrates two variants of such a solution:
Listing 4. The 'gaps' solution

-- First variant without SQL Server date/time function
SELECT t1.col1 AS startOfGap, MIN(t2.col1) AS endOfGap
   FROM
   (SELECT col1 = theDate + 1  FROM sampleDates tbl1
      WHERE NOT EXISTS(SELECT * FROM sampleDates tbl2
                      WHERE tbl2.theDate = tbl1.theDate + 1)
      AND theDate <> (SELECT MAX(theDate) FROM sampleDates)) t1
   INNER JOIN
   (SELECT col1 = theDate - 1  FROM sampleDates tbl1
      WHERE NOT EXISTS(SELECT * FROM sampleDates tbl2
                      WHERE tbl1.theDate = tbl2.theDate + 1)
      AND theDate <> (SELECT MIN(theDate) FROM sampleDates)) t2
   ON t1.col1 <= t2.col1
   GROUP BY t1.col1;


Results:

startOfGap endOfGap
----------------------- -----------------------
2007-01-04 00:00:00.000 2007-01-05 00:00:00.000
2007-01-07 00:00:00.000 2007-01-08 00:00:00.000
2007-01-10 00:00:00.000 2007-01-10 00:00:00.000
2007-01-12 00:00:00.000 2007-01-13 00:00:00.000
. . . . . . . . . . . . . . . . . . . . . . . .
2007-12-18 00:00:00.000 2007-12-18 00:00:00.000
2007-12-21 00:00:00.000 2007-12-22 00:00:00.000
2007-12-24 00:00:00.000 2007-12-24 00:00:00.000
2007-12-26 00:00:00.000 2007-12-27 00:00:00.000

(108 row(s) affected)


-- Second variant with SQL Server date/time functions
SELECT t1.col1 AS startOfGap, MIN(t2.col1) AS endOfGap
   FROM
   (SELECT col1 = DATEADD(dd, 1, theDate) FROM sampleDates tbl1
      WHERE NOT EXISTS(SELECT * FROM sampleDates tbl2
                  WHERE DATEDIFF(dd, tbl1.theDate, tbl2.theDate) = 1)
     AND theDate <> (SELECT MAX(theDate) FROM sampleDates)) t1
   INNER JOIN
   (SELECT col1 = DATEADD(dd, -1, theDate) FROM sampleDates tbl1
     WHERE NOT EXISTS(SELECT * FROM sampleDates tbl2
                  WHERE DATEDIFF(dd, tbl2.theDate, tbl1.theDate) = 1)
     AND theDate <> (SELECT MIN(theDate) FROM sampleDates)) t2
    ON t1.col1 <= t2.col1
    GROUP BY t1.col1
    ORDER BY t1.col1;



Results:

startOfGap endOfGap
----------------------- -----------------------
2007-01-04 00:00:00.000 2007-01-05 00:00:00.000
2007-01-07 00:00:00.000 2007-01-08 00:00:00.000
2007-01-10 00:00:00.000 2007-01-10 00:00:00.000
2007-01-12 00:00:00.000 2007-01-13 00:00:00.000
. . . . . . . . . . . . . . . . . . . . . . . .
2007-12-18 00:00:00.000 2007-12-18 00:00:00.000
2007-12-21 00:00:00.000 2007-12-22 00:00:00.000
2007-12-24 00:00:00.000 2007-12-24 00:00:00.000
2007-12-26 00:00:00.000 2007-12-27 00:00:00.000

(108 row(s) affected)
------------------------------------------------------------------
Both queries from the Listing 4 use self-join and produce the same result in approximately the same time. However, if you test the queries on a larger sample set; for ten years, for example, instead of one year, you will find that the second query runs much faster than the first one.
The reason for such a difference in performance is the way in which the queries deal with dates.
The first query uses an arithmetic operator (+) in order to add one day to the date. The second query for the same operation employs SQL Server built-in function.
(You can read the article “Best Practices for Date/Time Calculations in SQL Server” , which explains, why it is possible to use the arithmetic operators in date/time calculations and why you should avoid such a usage.
The first query from the Listing 4 is typical in showing how the use of arithmetic operations in date/time calculations can decrease the queries’ performance.)
So far, we examined the technique #2 on relatively small data sets.
There are, however, the situations when the amount of data that needs to be processed will be significantly larger. For example, your system may collect the POS (point of sale) transactions from multi-chain department and grocery stores located in different countries and (or) time zones.
In that case, if you asked to find the missing minutes (seconds) in a few months or even years, you may find that the fastest (second) query from the Listing 4 is also inefficient.
Then, you will need to enhance your queries in order to get the acceptable execution time.
One possible enhancement would be to employ an auxiliary column, as shown in the Listing 5:
Listing5. Enhanced solutions for gaps

-- Solution with identity column
IF EXISTS(SELECT * FROM sysobjects
   WHERE ID = (OBJECT_ID('sampleDates2')) AND xtype = 'U')
DROP TABLE sampleDates2;
CREATE TABLE sampleDates2(n INT IDENTITY(1,1) PRIMARY KEY, theDate datetime);
INSERT INTO sampleDates2(theDate) SELECT theDate FROM sampleDates;

SELECT DATEADD(dd, 1, a.theDate) AS startOfGap,
       DATEADD(dd, -1, b.theDate) AS endOfGap
   FROM sampleDates2 a INNER JOIN sampleDates2 b
   ON a.n = b.n - 1
   WHERE DATEDIFF(dd, a.theDate, DATEADD(dd, -1, b.theDate)) <> 0
GO

-- Solution with ROW_NUMBER() function
SELECT DATEADD(dd, 1, a.theDate) AS startOfGap,
       DATEADD(dd, -1, b.theDate) AS endOfGap
   FROM
     (SELECT ROW_NUMBER() OVER(ORDER BY (theDate)) AS RowNum, theDate
        FROM sampleDates) a
   INNER JOIN
     (SELECT ROW_NUMBER() OVER(ORDER BY (theDate)) AS RowNum, theDate
        FROM sampleDates) b
   ON a.RowNum = b.RowNum - 1
   WHERE DATEDIFF(dd, a.theDate, DATEADD(dd, -1, b.theDate)) <> 0
GO

-- Solution with common table expression
WITH sampleCTE(rowNum, theDate) AS
(
   SELECT ROW_NUMBER() OVER(ORDER BY theDate) AS RowNum, theDate
        FROM sampleDates
)
SELECT DATEADD(dd, 1, a.theDate) AS startOfGap,
       DATEADD(dd, -1, b.theDate) AS endOfGap
   FROM sampleCTE a INNER JOIN sampleCTE b
   ON a.RowNum = b.RowNum - 1
   WHERE DATEDIFF(dd, a.theDate, DATEADD(dd, -1, b.theDate)) <> 0

--------------------------------------
The queries from the Listing 5 are based on the idea of SQL Server MVP Erland Sommarskog (Stockholm).
All you need to do is to assign the order number to each row in the table and then to compare the values (they can be dates or numbers or even letters) in the adjacent rows, using the order numbers.
The first query in the Listing 5 uses the identity column in order to enumerate the rows in the table.
The second and third queries use ranking function ROW_NUMBER().
All three queries are much faster than the fastest (second) query from the Listing 4.
Note, that queries from the Listing 5 require column theDate (table sampleDates) to be sorted before assigning the order number. Since table sampleDates has a primary key constraint, the clustered index is also created on column theDate. That means you don’t need to sort the data in table sampleDates explicitly: clustered index will do that automatically.
One more thing that you should note is the incomplete results, returned by all the queries from the Listing 4 and Listing 5.
Indeed, Jan 01, Dec 30 and Dec 31 are missing dates in table sampleDates. However, they are not shown in the result as the gaps, because all the queries treat Jan 02, 2007 as the beginning and Dec 29, 2007 as the end of the sample data set.
In order to get the correct result, you need to insert the dates Dec 31, 2006 and Jan 01, 2008 into the table sampleDates.
Technique #3 –the Pivot table
One more technique presents missing dates in the form of the spreadsheet.
This type of output is one of the most attractive for the human eye and probably is the favorite document type of your boss.
The technique shown in the Listing 6, uses SQL Server 2005 PIVOT operator in order to produce tabular output:
Listing6. Solution with PIVOT operator

SELECT *
  FROM
  (SELECT
CONVERT(VARCHAR(13),DATEADD(dd,num,'Dec 31, 2006'),107) AS  missingDate,
  DATEPART(yy, DATEADD(dd, num, 'Dec 31, 2006')) YearNum,
  DATEPART(wk, DATEADD(dd, num, 'Dec 31, 2006')) Wk_Year,
  DATENAME(dw, DATEADD(dd, num, 'Dec 31, 2006')) weekDayName
   FROM sequence t1 LEFT OUTER JOIN sampleDates t2
   ON DATEADD(dd, t1.num, 'Dec 31, 2006') = t2.theDate
   WHERE t2.theDate IS NULL
  ) sourceTable
PIVOT
(MIN(missingDate)
FOR weekDayName
IN
(Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday)) AS pivotTable;



------------------------------------------------------------------------------
The beauty of the query from the Listing 6 is not only in its cross-tab view. That query also shows days of the week, which is very convenient, when you need to analyze business (application) that runs not whole week, let us say 5-6 days per week. In that case, the missing Saturdays and Sundays will be considered as weekends, but not as the missing days.
How To Find The Missing Hours
This bonus example shows how to apply the above techniques to the case of missing hours
You can also use this paragraph as a reference, when you need to find missing minutes or seconds.
First, create a sample data set (see Listing 7):
Listing7. Create sample data set for hours

-- Generate hours for the year 2007
DECLARE    @iniDate smalldatetime;
SELECT @iniDate = 'Dec 31, 2006';
IF EXISTS(SELECT * FROM sysobjects
   WHERE ID = (OBJECT_ID('sampleDates_2')) AND xtype = 'U')
DROP TABLE sampleDates_2;
CREATE TABLE sampleDates_2(theDate smalldatetime PRIMARY KEY);

INSERT INTO sampleDates_2
SELECT DATEADD(hh,num-1, days) hours
   FROM (SELECT DATEADD(dd, num, @iniDate) days
           FROM sequence) t1
   CROSS JOIN sequence t2
   WHERE num <=24
   ORDER BY hours

-- Create gaps in the sequence of hours
DELETE sampleDates_2
   WHERE DATEDIFF(hh, 0, theDate)%4 = 0
   AND DATEDIFF(dd, 'Jan 01, 2007',theDate) < 100;
DELETE sampleDates_2
   WHERE DATEDIFF(hh, 0, theDate)%5 = 0
   AND DATEDIFF(dd, 'Jan 01, 2007',theDate) BETWEEN 50 AND 150;
DELETE sampleDates_2
   WHERE DATEDIFF(hh, 0, theDate)%7 = 0
   AND DATEDIFF(dd, 'Jan 01, 2007',theDate) BETWEEN 75 AND 325;

-- Just to make the last hour of the year missing
DELETE sampleDates_2 WHERE theDate = '2007-12-31 23:00:00';

-- In order to get the very first gap in the beginning of the year and
-- the very last gap at the end of the year, add the next dates
INSERT INTO sampleDates_2 VALUES('Dec 31, 2006 23:00:00');
INSERT INTO sampleDates_2 VALUES('Jan 01, 2008 00:00:00');

---------------------------------------------------------------
The following script shows the solutions for missing hours (see Listing 8):
Listing8. Solutions for missing hours

-- 1) The gaps solution for missing hours
WITH sampleCTE(rowNum, theDate) AS
(
   SELECT ROW_NUMBER() OVER(ORDER BY (theDate)) AS RowNum, theDate
        FROM sampleDates_2
)
SELECT DATEADD(hh, 1, a.theDate) AS startOfGap,
       DATEADD(hh, -1, b.theDate) AS endOfGap
   FROM sampleCTE a INNER JOIN sampleCTE b
   ON a.RowNum = b.RowNum - 1
   WHERE DATEDIFF(hh, a.theDate, DATEADD(hh, -1, b.theDate)) <> 0;

-- 2) The cross-tab solution that counts the number of missing hours per each day
WITH sourceTable(hours, days, weekDayName) AS
(
   SELECT 
       t3.hours,
       CAST(DATEDIFF(dd, 0, t3.hours) AS smalldatetime) days,
       DATENAME(dw, t3.hours) weekDayName
       FROM (SELECT DATEADD(hh,num-1, days) hours, t2.num
   FROM
   (SELECT DATEADD(dd, num, 'Dec 31, 2006') days
       FROM sequence) t1 CROSS JOIN sequence t2
       WHERE num <=24) t3 LEFT OUTER JOIN sampleDates_2 t4
       ON t3.hours = t4.theDate
       WHERE t4.theDate IS NULL
)
SELECT *
  FROM sourceTable
  PIVOT
(COUNT(hours)
FOR weekDayName
IN
(Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday)) AS pivotTable;

-- 3) The cross-tab solution that shows missing hours per each day
SELECT *
  FROM
  (SELECT  CONVERT(VARCHAR(15), t3.hours, 108) hours,
           t3.num - 1 AS dayHour,
           DATEPART(mm, t3.hours) monthNum,
           DATEPART(dd, t3.hours) dateNum,
           CONVERT(VARCHAR(13), t3.hours, 107) days
       FROM (SELECT DATEADD(hh,num-1, days) hours, t2.num
   FROM
   (SELECT DATEADD(dd, num, 'Dec 31, 2006') days
       FROM sequence) t1 CROSS JOIN sequence t2
       WHERE num <=24) t3 LEFT OUTER JOIN sampleDates_2 t4
       ON t3.hours = t4.theDate
       WHERE t4.theDate IS NULL
) sourceTable
PIVOT
(MIN(hours)
FOR dayHour
IN
([0],[1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12],
[13],[14],[15],[16],[17],[18],[19],[20],[21],[22],[23])) AS pivotTable;

----------------------------------------------------------------------------
The first solution from the Listing 8 shows the missing hours as the beginning and the end of the gap.

The second solution shows the number of missing hours per each day

If this is not enough, the third solution will give you detailed information about missing hours.
The Task Completed: Here Are The Results

You found missing dates and sent the results to your boss. After short investigation, the problem was identified: some data has been deleted from database by mistake, during the application upgrade.

In that situation, everybody relied on you and once again, you rose to the challenge. You found the old backup, restored the database under another name and moved the missing data to the original database.

Here is the result of your efforts:

The customer is satisfied. The manager impressed by your skills. You can be proud of your achievements.

Izenda training videos