Thursday, July 21, 2011

DATEDIFF (Transact-SQL) showing wrong values


DATEDIFF (Transact-SQL) showing wrong values

Today I was asked to change a query that was showing the result of last 2 weeks. I have to change the filter criteria of date from last 2 weeks to last 2 months as current query was written like this

where DateDIFF(ww, Employees.JoinDate,getDate())<=2

It was used for to get all employees have join date is less or equal to 2 weeks , so I just change the datepart from week to month as mm and chagne the above line to

AND DateDIFF(mm, Employee.StartDate,getDate())<=2 (I was thinking that it would work to get records for last 2 months ) but when I did some unit testting then I have come to know that it showing the wrong result even those records was also showing which date is more then last 2 months .Then I tried to check the behavior of datediff with different example and reading its documentation form online book (Returns the number of date and time boundaries crossed between two specified dates.) from msdn

The example I tried:

SELECT DATEDIFF(mm,'2011-05-01','2011-07-31')  AS Months

Months

-----------

2



(1 row(s) affected)



And the same start and end date but using datepart day instead of month showing as

SELECT DATEDIFF(dd,'2011-05-01','2011-07-31') AS Days

Days

-----------

91



(1 row(s) affected)

It was showing 91 days but if we execute the query with month it showing 2 months so then I come to know that datediff only cares about boundaries as it was showing 91 days difference because 90 days has been passed but it only shows 2 month difference when using month as datepart because the month boundary is 2 as start date month is 5 and end date month is 7.

Let me show you another example

DECLARE @startdate DATETIME

DECLARE @enddate   DATETIME

SET @startdate = '2010-12-19'  December 19 , 2011

SET @enddate = '2010-12-25'   December 25 , 2011

    

SELECT DATEDIFF(dd,@startdate,@enddate) AS 'day',DATEDIFF(ww,@startdate,@enddate) AS 'Week'



day         Week

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

6           0



(1 row(s) affected)







It showing 0  week difference as week boundary did not pass yet and 19 and 25 are in same week of December 2010 that’s why it showing 0 week difference. See the December 2010 month screen shot





But If we changed the start date to 18 december 2011 and end date to 19 December 2011 it would show one week differece as these dates not fall in same week and difference is oen week.



DECLARE @startdate DATETIME

DECLARE @enddate   DATETIME

SET @startdate = '2010-12-18'

SET @enddate = '2010-12-19'

SELECT DATEDIFF(dd,@startdate,@enddate) AS 'day',DATEDIFF(ww,@startdate,@enddate) AS 'Week'

day         Week

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

1           1



(1 row(s) affected)



See here only 1 day difference and showing 1 week difference however in previous query it was showing only 0 week differce but we have 6 day difference this is because of boundaries that this function considering from datepar (i.e day or week).



Let see another example



DECLARE @startdate DATETIME

DECLARE @enddate   DATETIME

SET @startdate = '2010-12-31'

SET @enddate = '2011-01-1'

SELECT DATEDIFF(dd,@startdate,@enddate) AS 'day',DATEDIFF(ww,@startdate,@enddate) AS 'Week',DATEDIFF(mm,@startdate,@enddate) AS 'month',

DATEDIFF(yy,@startdate,@enddate) AS 'year'





    

day         Week        month       year

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

1           0           1           1



(1 row(s) affected)





Here result are very interesting as it shows 1 day difference but 0 week difference and more important 1 month and 1 year difference how this happened ?

Same logic as December 31, 2010 and January 01 , 2001 falls in same week so it did list 0 week difference but as month boundary crossed as start date month was December and enddate month is January hence it showed 1 month difference and same is the case for year becuae start date year is 2010 and end date year is 2011 hence it showed 1 year difference.



I hope now its clear the behavior of DateDiff function ,

So what I did for my query that need to show the record for last 2 months I just used like



where Employees.JoinDate >= DATEADD(m, -2, GETDATE())






Saturday, July 16, 2011

while attaching mdf file in sql server : Unable to open physical file - Operating system error 5: 5 (Access is denied)

i was having problem while attaching mdf file in sql server 2008 from my hard disk . When i tried to attach the mdf file i got the following error

Unable to open physical file - Operating system error 5: 5 (Access is denied)


then i just copied that file into defulat directory of sql server 2008 database "C:\Program Files\Microsoft SQL Server\MSSQL10_50.MSSQLSERVER\MSSQL\DATA" and tried to attach and it was attached successfully but I was wondering why its not be able to attach if i do this file from other location then after some googling i have come to know that it was some permission issue and i can attach this from other location too , just need to give rights to user (under which sql server was running) on that folder where my mdf is placed.

then first i check from management studio that-> sql server configuration tool that under which account sql server is running and it was "NETWORK SERVICE" then i just granted full permission to that user on the folder where my mdf was placed and i was able to attach it.





Monday, July 11, 2011

How to Query Linked Server in SQL Server --- CRUD operation on LinkedServer

In this post I will show how to perform CRUD opertions on linked server in sql server

For this i have created a simpel DB named "TestDB" which contains one table "Employee" and 2 columns (ID (int, pk), name varchar(1000)

First need to add link server where the above database is created . You can create link server as mentioned in msdn.
http://msdn.microsoft.com/en-us/library/ff772782.aspx

 Now I will explain CRUD Opertion one bye one

  • Create / Insert
    there are two ways to do
    INSERT INTO [otherPC\SQLInstace2008].TestDB.dbo.Employee(Name) VALUES( 'hafiz')
    or
    insert openquery ([otherPC\SQLInstace2008], 'select [name] from TestDB.dbo.Employee')VALUES('suleman')

  • Retervie / SelectSELECT *  FROM [otherPC\SQLInstace2008].TestDB.dbo.Employee
    SELECT *FROM OPENQUERY([otherPC\SQLInstace2008], 'SELECT * FROM  TestDB..Employee')
    SELECT *FROM OPENQUERY([otherPC\SQLInstace2008], 'SELECT * FROM  TestDB.dbo.Employee')

  • Update
    update openquery ([otherPC\SQLInstace2008], 'SELECT * FROM  TestDB.dbo.Employee where name = ''suleman'' ') SET name = 'hafiz suleman'
    OR
    UPDATE [otherPC\SQLInstace2008].TestDB.dbo.Employee SET name = 'muhammad suleman' WHERE name = 'hafiz'

  • Delete
    delete openquery ([otherPC\SQLInstace2008], 'select * from TestDB.dbo.Employee where name = ''muhammad suleman''')
    OR
    DELETE FROM [otherPC\SQLInstace2008].TestDB.dbo.Employee WHERE name='hafiz suleman'
If you found any error like this

The operation could not be performed because OLE DB provider "SQLNCLI10" for linked server "SERVERNAME.REDMOND.CORP.MICROSOFT.COM" was unable to begin a distributed transaction.

then use followign statement to fix the issue.

EXEC sp_serveroption @server = 'YourServerName',@optname = 'remote proc transaction promotion', @optvalue = 'false' ;


  

 

Friday, July 1, 2011

CREATE DATABASE permission denied in database "master". An attempt to attach an auto-named database for file XXX failed.

i was having issue on asp.net 4.0 website on windows 2008 R2 server ,CREATE DATABASE permission denied in database ‘master’. An attempt to attach an auto-named database for file XXX failed.

i did some search on internet and then came to know that we need to give site access to netwrok user  as application was running under network service user (in default application pool) , i did tried to do so but error was not removed , then i just changed the user from network to local system in application pool and it started work without any issue.



Biztalk : Error Threshold on Receive Locations and receive location disabled automaticaly

we have one receive location of type SQL in our Biztalk Application on productin server and it got disabled after some days and logged an error in event log  like that "Threshol on Receive Location"

it was very annoying for us to enable it manually and we were not be able to find the root cause of this problem, then after some R&D i have come to know that

Biztalk keeps polling sql server after  every x milliseconds. In some cases its configurable. For some adapters its not.

we have error threshold value set to 5 , mean after 5 continous error from sql server the receive location would be disable as Microsoft says about Error Trhreshold :

The Error Threshold is used to specify the maximum number of continuous errors received before disabling the receive handler.

so when for some maintaine work or with due ot any other reason if sql server is down and Biztalk got 5 continous error from sql server then it disabled the receive location and put some error in log related to threshold.

so what we did just change the value of ErrorThreshold from 5 to 500 and restart the host instance then we did not face this issue again.

Biztalk Error X2044 : symbol Object is already defined; the first definition is in assembly c:\###.dll

Yesterday I was hacing an error  in Biztalk 2010  ,

symbol '###' is already defined; the first definition is in assembly c:\###.dll , in my case it was saing that a porttype is alrdeay defined, so what how to fix these kind of issues in biztalk. error x2044


  1. Open the orchestration in Notepad (In my case SchoolOrchestration.odx)

  2. find (Ctrl+F) for “#endif // __DESIGNER_DATA”

  3. Delete all the code below that line

  4. Save your file in Notepad

  5. Say yes when Visual Studio asks if you want to update your file

  6. Recompile


that's it .

Source : http://biztalkia.blogspot.com/2005/12/solving-biztalk-error-x2044.html