Wednesday 28 December 2011

Orphaned Database Snapshots prevents mds configuration manager database connection


Problem:


Orphaned database snapshots in dev and test environments can stop you being able to use the MDS Configuration Manager to connect to the database. This occurs if you restore the mdm_hub database when a database snapshot exists on the target server. Because the snapshot is orphaned it gets left in SUSPECT mode.

SELECT name,state_desc  FROM sys.databases

Solution:

Delete the database snapshot and make sure the database is in ONLINE mode.

More Info:

To check for the error you can run a profiler trace which will bring up an Exception 926 when trying to connect with configuration manager.
Books online error 926

Friday 23 December 2011

Viewing job history via T-SQL

This SQL Server script will display job history. The benefit of this script over displaying it from the GUI is that you get to see the job durations quickly. You will need to replace with the job you want to see history for.




select job_name, run_datetime, run_duration
from
(
select job_name, run_datetime,
SUBSTRING(run_duration, 1, 2) + ':' + SUBSTRING(run_duration, 3, 2) + ':' +
SUBSTRING(run_duration, 5, 2) AS run_duration
from
(
select DISTINCT
j.name as job_name,
run_datetime = CONVERT(DATETIME, RTRIM(run_date)) +
(run_time * 9 + run_time % 10000 * 6 + run_time % 100 * 10) / 216e4,
run_duration = RIGHT('000000' + CONVERT(varchar(6), run_duration), 6)
from msdb..sysjobhistory h
inner join msdb..sysjobs j
on h.job_id = j.job_id
) t
) t
WHERE job_name = ''
order by job_name, run_datetime

Great Plains Document Locks

Overview

The following code is useful to find who has a document locked in Great Plains.
For example if someone has a sales document open during fulfilment it will fail... so we need to check who is in the document to get them to come out of it.

T-SQL to find who has document locks in Great Plains



USE DYNAMICS

DECLARE curLocks CURSOR
FOR SELECT sqlSessions.login_name, LOCK.table_path_name, LOCK.row_id
FROM tempdb..DEX_LOCK LOCK
INNER JOIN tempdb.dbo.DEX_SESSION SESS
ON LOCK.session_id = SESS.session_id
INNER JOIN master.sys.dm_exec_sessions sqlSessions
ON SESS.sqlsvr_spid = sqlSessions.session_id

DECLARE @name varchar(40)
DECLARE @table_path_name varchar(80)
DECLARE @row_id int
OPEN curLocks

FETCH NEXT FROM curLocks INTO @name, @table_path_name, @row_id
WHILE (@@fetch_status <> -1)
BEGIN
IF (@@fetch_status <> -2)
BEGIN

DECLARE @sql varchar(1000)
SELECT @sql = 'select ''' + @name + ''' AS [LOGIN NAME], * from
' + RTRIM(@table_path_name) + ' where dex_row_id = ' + CAST(@row_id AS VARCHAR(50))
EXEC (@sql)

END
FETCH NEXT FROM curLocks INTO @name, @table_path_name, @row_id
END

CLOSE curLocks
DEALLOCATE curLocks
GO

Thursday 8 December 2011

Excel dates do not match SQL Server dates

Overview

There is a bug in excel that number representations for dates (ie 1 = 01/01/1900) do not match up with SQL Server number representations for dates. Apparently this is something that is known but will not be fixed as it will break to many peoples spreadsheets!


How dates work in Excel

Dates in excel are really just numbers formatted as a date. This picture shows the first column as the number representation of the date. All i have done is to copy the column across to B and reformat it to a Date column.



The Bug

This shows there is a 29 Feb 1900 when it never existed! So it adds another date to the calender, thereby ruining any sort of consistency with the number representation of the date.





In SQL Server

Dates work the same way in SQL Server except they start from 0 rather than 1.
DateID      SQL Dates
----------- -----------------------
0 1900-01-01 00:00:00.000
1 1900-01-02 00:00:00.000
2 1900-01-03 00:00:00.000
3 1900-01-04 00:00:00.000

And in SQL Server the dates are correct...

SELECT 58 AS DateID, CONVERT(DATETIME,58) AS [SQL Dates] UNION ALL
SELECT 59, CONVERT(DATETIME,59) UNION ALL
SELECT 60, CONVERT(DATETIME,60) UNION ALL
SELECT 61, CONVERT(DATETIME,61)

Returns the following

DateID      SQL Dates
----------- -----------------------
58 1900-02-28 00:00:00.000
59 1900-03-01 00:00:00.000
60 1900-03-02 00:00:00.000
61 1900-03-03 00:00:00.000

So what you get in the end that it can be complicated to link the dates to Excel if you are trying to match up Excel to SQL Server with the number representation of the date

Friday 2 December 2011

Unit Testing Framework with tSQLt and Redgate SQLTest

Overview

tSQLt allows you to implement unit tests in T-SQL. Unit testing will help us get to a stage where we are doing continuous integration, test driven development and Agile Development.

Redgate have released a user interface for tSQLt that integrates directly into SSMS
http://www.red-gate.com/products/sql-development/sql-test/

What is tSQLt?

http://tsqlt.org/
tSQLt is a database unit testing framework for Microsoft SQL Server. tSQLt is compatible with SQL Server 2005 (service pack 2 required) and above on all editions.

How to install

  1. Go to http://www.red-gate.com/products/sql-development/sql-test/
  2. Download the preview version
  3. Install on your machine where SSMS is installed (you will have to close SSMS)

Are there an server components installed?

Yes. You will be prompted when you open SSMS. These are the changes it makes to a database you are doing unit testing on..

A Hello World Example

Create a procedure you want to test




USE [tSQLt_Example]
GO
CREATE PROCEDURE [dbo].[getHelloWorld]
@pass BIT,
@HELLO VARCHAR(15) OUTPUT
AS
BEGIN

/*
Return Hello World or Goodbye depending on @pass param
*/
IF @pass = 1
SET @HELLO = 'Hello World!'
ELSE
SET @HELLO = 'Goodbye World!'

END
GO


Create your unit Test stored procedure

In SSMS in the SQL Test window, choose 'New Test...'

Depending what version you are on depends what happens here (anything prior to 2008R2 means you just have the write the sproc, i couldn't get anything else to happen)



USE [tSQLt_Example]
GO
Create PROCEDURE [AcceleratorTests].[testHelloWorld]
AS
BEGIN

/*
Return Hello World!
*/
DECLARE @ret VARCHAR(15)
EXEC getHelloWorld @pass = 1, @HELLO = @RET OUTPUT

/*
Check Hello World is returned
*/
EXEC tSQLt.AssertEqualsString 'Hello World!', @ret

END ;
GO


You will end up with a test in the SQL Test window if you choose refresh

Running your tests

Choose 'Run Tests' from the SQL Test window and there will be a tick or cross as to whether your test passed.

Fail Example

To see a failed test example alter the getHelloWorld stored procedure to pass in a 0 for the @pass parameter
eg. EXEC getHelloWorld @pass = 0, @HELLO = @RET OUTPUT

This is what the SQL Test window shows

And output in the SQL Test Messages



[AcceleratorTests].[testHelloWorld] failed: Expected: but was:

Related stuff

http://www.red-gate.com/products/sql-development/sql-test/
http://tsqlt.org/