Thursday, June 22, 2017

Rerunning a SSRS subscription report

Yesterday I had a situation where  a couple of SSRS reports failed due to a network upgrade.

The SSRS report was not able to access the SQL server that was being used in the stored procedure.

So I had to rerun the report subscription manually.

To re-run the SSRS report subsciption I followed two steps.

Step 1:

I have used the below query to identify the job id of the failed reports.

     S.ScheduleID AS SQLAgent_Job_Name, Sub.LastStatus, sub.LastRunTime, LastRunStatus
     ,SUB.Description AS Sub_Desc
     ,SUB.DeliveryExtension AS Sub_Del_Extension
     ,C.Name AS ReportName
     ,C.Path AS ReportPath

FROM ReportSchedule RS
     INNER JOIN Schedule S ON (RS.ScheduleID = S.ScheduleID)
     INNER JOIN Subscriptions SUB ON (RS.SubscriptionID = SUB.SubscriptionID)
     INNER JOIN [Catalog] C ON (RS.ReportID = C.ItemID AND SUB.Report_OID = C.ItemID)
sub.LastRunTime > GETDATE() - 1 and  C.Name LIKE 'Reportname' 

Step 2:

I have copied the scheduleid and used a filter in the Jobs of the SSRS server as shown below.

Then Right click the Job and click 'Start Job at Step'

There are several other practices to achieve the same result.but I find that this is easier to follow.

Monday, June 12, 2017

Find the stored procedures and agents that use Linked Server

Today I had a scenario where I had to identify all the stored procedures and agents that used a particular Linked Server.  We are thinking of getting rid of these multiple  Linked Servers and combining them into one server.

So I have used the sys.sql_modules table to find out what stored procedures are using these linked servers.

The code I have written is as follows.

SELECT OBJECT_NAME(object_id) object ,  *
      FROM sys.sql_modules
Definition LIKE '%linkedsrv1%'
Definition Like '%linkedsrv2%'
 Definition Like '%linkedsrv3%'
      AND OBJECTPROPERTY(object_id, 'IsProcedure') = 1 ;

I have also used the sysjobsteps and sysjobs tables from msdb database to find out what jobs are using these Linked Servers,

The code I have written is as follows:

  SELECT AS JobName,js.command
      FROM msdb.dbo.sysjobsteps jsteps
         INNER JOIN msdb.dbo.sysjobs jobs
            ON jobs.job_id = jsteps.job_id
 jsteps.command LIKE   '%linkedsrv1%'
jssteps.command Like  '%linkedsrv2%'
 jsteps.command Like  '%linkedsrv3%'

Next question that I am pondering is if we consolidate these servers into one server, what are the considerations I need to be aware of.

I will be covering this in a future post.  Meanwhile appreciate some feedback from the readers.

Tuesday, June 06, 2017

Sending Automatic Emails from SQL server

I am excited to reactivate my blog after 2.5 years.

I have written a stored procedure last week to send automated emails to customers based on certain criteria.

To identify this there is a stored procedure that requires some parameters.

The steps followed for creating the stored procedure are as follows:

  • There is already an existing stored procedure that creates a temp table and inserts data into that temp table.
  • In the new stored procedure define a new temp table.
  • Insert data into this temp table by executing the existing stored procedure
  • Declare new variables to hold the needed for the email.
  • In a while loop assign the data to the above variables for each record and send the email one by one using sp_send_dbmail built in stored procedure.
Here is the skeleton code I came up with for the procedure.  I have configured a HTML email


Declare @temp_table table
ID INT IDENTITY(1, 1) primary key ,
  field1 varchar(60) null,
AccountID VARCHAR(25) null,
AccountName varchar(200) null,
AccountEMail varchar(128) null

-- Insert into the temp table variable -- the list to be emailed by running the stored procedure Proc1

Insert into @temp_table


Exec [Proc1]
@Parameter1 = 'NZIO',
@Parameter2 = 1,

-- Declare new variables

DECLARE @accountemail varchar(60)
DECLARE @accountname varchar(60)
DECLARE @rowcount INT
DECLARE @href1 varchar(256)

--setting count to start from first row
SET @count = 1
SET @rowcount = (SELECT count(*) FROM @temp_table)
--Print @rowcount

--loop to send email from temp table

WHILE(@count < @rowcount)
SET @accountemail = (SELECT AccountEMail FROM @temp_table where Id = @count and AccountEMail LIKE '%_@__%.__%')
SET @accountname = (SELECT AccountName FROM @temp_table where Id = @count and AccountEMail LIKE '%_@__%.__%')
SET @href1 = (SELECT CASE When ClientMode = 'UNATTENDED (HANDS-FREE)' then 'http://link1.pdf' else 'http://link.pdf' END FROM @temp_table where Id = @count and AccountEMail LIKE '%_@__%.__%')

--Configure Email body


SET @tableHTML =

Automatic Notification -- Please do not reply

' +
N'Good Morning  ' +
cast(@accountname as nvarchar(max)) +
N' We are contacting you to let you know that blah blah (EDI: ' +
cast(@field1 as nvarchar(max)) +
is not working.  Please have a look at your account+ cast(@accountname as nvarchar(max)) +
N' Please click on the below link to view user guide on starting
' + N' Userguide for Windows ' +
N' Regards BI Support '


-- Send email using Database Mail

--USE msdb
EXEC MSDB.dbo.sp_send_dbmail @profile_name='Testreport',
@copy_recipients = @accountemail,
@recipients = '',
@subject='Test message',
@body= @tableHTML,
@body_format = 'HTML' ;

SET @count= @count +1



Wednesday, February 26, 2014

Getting the first date of the month in SQL without any functions

One of the date columns in my database is an integer as it is a dimension key
I was trying to get some results grouped for the whole month by this date integer column.

This is how I went about getting it in an easier manner without using any DATEADD and DATDIFF functions

Let us say that the date column name is dim_date_key which is an integer data type

So I used the following SQL code to get the sum of the amount for the month

select sum(amount), dim_date_key/100*100 + 1 month_start_Date from table_name
where dim_date_key/100*100 + 1 >= 20130401
group by dim_date_key/100*100 + 1

Here if we just look at the expression dim_process_date_key/100*100 +1 in mathematical terms it is confusing as to how this can get the start of the month.

But the key here is the integer data type of the date column.

  • When the expression is evaluated, the expression dim_process_date_key/100 gets evaluated first.  This gives the answer as 201304 since the data type is an integer.
  • Then the expression 201304 * 100 is evaluated which yeilds the result as 20130400 which is an integer.  
  • Then the expression 20130400 + 1 is evaluated which yeilds the start date of the month which is 20130401

Wednesday, January 15, 2014

Import/Export data wizard in MSSQL 2008 R2 Errors -- Resolved

Today I was using the import export wizard to import data from one of the database in the production system to the database in the development system.

To do this -- Right click on the database (in the development system) choose -- tasks -- Import data
Follow the steps in the data wizard for choosing the source and destination tables.  I used the write a query to copy the data option.

Checked the mappings
and clicked Finish

I expected the wizard to run without any problems.  But................ the following errors were thrown.

- Copying to [dbo].[FACT_ACCOUNT_TRANSACTION] (Error)
Error 0xc0202009: Data Flow Task 1: SSIS Error Code DTS_E_OLEDBERROR.  An OLE DB error has occurred. Error code: 0x80004005.
An OLE DB record is available.  Source: "Microsoft SQL Server Native Client 10.0"  Hresult: 0x80004005  Description: "The INSERT permission was denied on the object 'FACT_ACCOUNT_TRANSACTION', database 'BIW', schema 'dbo'.".
 (SQL Server Import and Export Wizard)

Error 0xc0209029: Data Flow Task 1: SSIS Error Code DTS_E_INDUCEDTRANSFORMFAILUREONERROR.  The "input "Destination Input" (128)" failed because error code 0xC020907B occurred, and the error row disposition on "input "Destination Input" (128)" specifies failure on error. An error occurred on the specified object of the specified component.  There may be error messages posted before this with more information about the failure.
 (SQL Server Import and Export Wizard)

Error 0xc0047022: Data Flow Task 1: SSIS Error Code DTS_E_PROCESSINPUTFAILED.  The ProcessInput method on component "Destination - FACT_ACCOUNT_TRANSACTION" (115) failed with error code 0xC0209029 while processing input "Destination Input" (128). The identified component returned an error from the ProcessInput method. The error is specific to the component, but the error is fatal and will cause the Data Flow task to stop running.  There may be error messages posted before this with more information about the failure.
 (SQL Server Import and Export Wizard)

Error 0xc02020c4: Data Flow Task 1: The attempt to add a row to the Data Flow task buffer failed with error code 0xC0047020.
 (SQL Server Import and Export Wizard)

Error 0xc0047038: Data Flow Task 1: SSIS Error Code DTS_E_PRIMEOUTPUTFAILED.  The PrimeOutput method on component "Source - Query" (1) returned error code 0xC02020C4.  The component returned a failure code when the pipeline engine called PrimeOutput(). The meaning of the failure code is defined by the component, but the error is fatal and the pipeline stopped executing.  There may be error messages posted before this with more information about the failure.
 (SQL Server Import and Export Wizard)

Finally I resolved this error by dropping the column store index on the table and rerunning the wizard.

And then recreated the column store index after the data has been copied.

Monday, December 23, 2013

Work Directory in ODBC Connection is empty

 "Work Directory in ODBC Connection is empty, unable to proceed."

 That was the error I was getting today when I was trying to load a table from MDS using Wherescape Red. At first I didnot understand why there is a work directory needed. When I looked at the MDS cnnection settings The default Load was set to Native ODBC and the work directory was not set as shown below.


 As soon as I have set the directory to c:\ the loading of the table worked.

 Because the Native ODBC load reads all the data and creates temporary tables, this method of data loading requires a work directory to be specified so that the data is written in batch mode rather than one row at a time similar to ODBC load. When the reading a writing takes place one row at a time we need not specifiy the work directory. But the native ODBC load is faster because of a batch write process.

Ensure that a process for deleting the temporary tables is in place if you are loading using Native ODBC.

If you are using the ODBC Load there is no need to specify the work directory.

Tuesday, August 20, 2013

ERROR 22-322: Syntax Error is SAS code

I have been in hibernation for too long now. I have changed jobs and now hjaving an opportunity to work on SAS code after nearly 11 years. Today I was running a SAS program and got the following error.

ERROR 22-322: Syntax error, expecting one of the following: a name, -, :, FORMAT, INFORMAT, LABEL, LABEL, LENGTH,

To resolve this as the error suggested there was a syntax error in my code where I was not using the proper syntax in the ATTRIB statement I was using

Name label 'Employee Name';

Here the label statement needs an '=' so when I change this to the following statement

Name label = 'Employee Name' ;

the sas code was executed successfully.

Rerunning a SSRS subscription report

Yesterday I had a situation where  a couple of SSRS reports failed due to a network upgrade. The SSRS report was not able to access the SQ...