Simon Sabin UK SQL Consultant's Blog

 

We are organising the next SQLBits and would love you to help out.

The event isn't possible without the kind support from everyone in the SQL community, if you want to be part of the team that runs SQLBits then let us know. We've have loads of things we have to do from managing sponsors to stuffing swag bags so the more helpers the better.

If you are interested then send us an email to contactus@sqlbits.com

 

Posted by simonsabin | 1 comment(s)

 

Orcsweb are kindly upgrading the hosting account that we are using for SQLBits. This is so that we can host all the great videos we have of SQLBits, and hopefully do more.

If you are considering getting hosting then Orcsweb are very good and there support is fantastic.

A big thank you to Orcsweb for providing us this service

 

Posted by simonsabin | with no comments

 

I do get frustrated sometimes by the very poor user experience you get with management studio.

My most recent annoyance comes when looking at job histories, if you want to look at the details of the step that failed you have to go and find the job, open it, find the job step and open it. If you've got loads of jobs this can take some time. Especially with the popup window behaviour of management studio.

This is a connect item that would allow us to double click on an item in the job history and open the job properties directly. I reckon for a moderately busy DBA this would save days of effort per year.

http://connect.microsoft.com/SQLServer/feedback/details/531889/allow-access-to-job-details-from-the-log-file-viewer-to-improve-manageability

If you think this would be a good suggestion then please vote for it.

 

Posted by simonsabin | 6 comment(s)

 

I've got two sessions at Devweek in March. (www.devweek.com ) There is a great lineup and some great sessions.

I'm trying to organise a panel discussion/social on evening with some of the SQL speakers like Greg Low , Davide Mauri and Itzik Ben-Gan. I will post when I have more details.

If you book in the next two weeks you get a £100 discount Book your place

View the complete DevWeek 2010 Session Schedule

 

Posted by simonsabin | 1 comment(s)

 

Colin has just blogged about a nasty error that occurs if you have your data and/or log files in the root of a cluster drive and you dettach the database.

Read Colin's blog post for more details http://sqlblogcasts.com/blogs/grumpyolddba/archive/2010/02/01/detach-a-database-and-take-out-a-cluster.aspx

 

Posted by simonsabin | 1 comment(s)

 

I'm in the process of reviewing the submissions for the last TSQL Challenge I posed. There were some really cool and inovative solutions. The prize for that will be a copy of the new SQL Server Troubleshooting book.

The new challenge will be posted soon.

 

 

 

 

 

Posted by simonsabin | 1 comment(s)

 

If you went to Developer Day 8 then make sure you complete the feedback.

http://developerdeveloperdeveloper.com/ddd8/feedback.aspx

Otherwise we don't know what you liked and disliked.

Thanks

 

Posted by simonsabin | 1 comment(s)

 

I've encountered this erro message a few times. One of the reasons this occurs is that the server can't verify and account with a domain controller. This happens when a user has access to a server through group membership. SQL doesn't know all the individuals in a group and so has to go off and find out. If the service account doesn't have the correct permissions or you have multiple domains then this can occur.

However the situation I had this week was that this was failing and none of the above were true.

The reason was that "Agent XPs" were disabled. Agent XPs are the extended stored procedures SQL Agent uses in its day to day job. The account verification process is an extended stored proc. That meant that when SQL Agent tried to verify a user it couldn't.

Annoyingly the error about "Agent XPs" didn't appear in the log for the job history but appeared in the SQL Agent error log. Mainy people don't know there is such a thing. Well there is. Since 2005 its easier to find but many still don't look there. This is a completely different log to that of the main SQL Server service.

I thought I could get around this by using a SQL account, but no luck. It still uses the extended stored proc.

So if you are running SQL Agent then you need to enable the "Agent XPs" using, the following. BOL states that this is done for you if you start SQL Agent through management studio. That could be a new feature in SQL 2008.

Note: If you have advanced options turned on then you don't have to turn it on again.

exec sp_configure 'advanced options', 1

reconfigure

exec sp_configure 'Agent xps', 1

reconfigure

exec sp_configure 'advanced options', 0

reconfigure

 

 

Posted by simonsabin | 1 comment(s)

 

I pointed out yesterday that the EntityFramework doesn't like smallints. Well it does and it doesn't The model handles them fine and the objects have datatypes of int16 which is great.

However the queries that are generated do this odd thing with any predicates on such columns. It applies a cast to column.i.e

where cast(col2 as int)= @d

At first glance I thought oh now not another screw up with the SQL from Entity framework, but on inspection of a query plan where the column in question was indexed I still got a seek operation. Very nice, well done optimisation team.

When I pointed this out, I was asked whether this worked on SQL2005. Having only got a SQL2008 instance on my laptop I took the question away for testing. The reason of the question could be related to the fact that in SQL 2008 the introduced the ability to cast a datetime to a date to be able to look for specific days of data and still use an index.

I have now tested and can state that it does work on SQL 2005.

 

Posted by simonsabin | 2 comment(s)
Filed under: ,

 

My code and presentation from my session at Developer Day 8 are now available here

DDD_8-Entity_Framework Code
Entity framework presentation

Any questions let me know.

Also for more on the new features in Entity Framework v next go to http://blogs.msdn.com/adonet/archive/2009/08/05/improvements-to-the-generated-sql-in-net-4-0-beta1.aspx

 

 

 You can watch all the sessions from SQLBits V now. They are available for download or for viewing online.

If there is a delay then just wait, the videos are high quality and so are very large.

These are the links to all the sessions

A whistlestop tour of SSIS add-ins
Achieve SQL Server 2008 High Availability and Disaster Recovery - technical case study
An introduction to Master Data Services
Building cubes from ODS or Operational Systems
Cache-warming strategies for Analysis Services 2008
Common Integration Services Problems
Creating High Performance Spatial Databases
Data & Backup Compression in SQL Server 2008
Data Visualisation with Bing Maps for Enterprise
Data Warehouse on a Fast Track forwards
Data warehousing features in SQL 2008
Designing for simplification
Designing I/O systems for SQL Server
Excel - An Excellent Data Mining Tool
Getting Dimensional with Data
I need my reports..........Yesterday!
Introducing Project Madison
Introducing SQL Server Master Data Services
Introduction of MS StreamInsight.
Introduction to the Microsoft BI Technology Stack
Let’s make SQL fly – a technical session for developers and administrators who believe in magic!
Lets go more functional - F# WHAT , WHY and BI
Microsoft SQL Server 2008 R2: What’s New in Reporting Services
Optimistic Concurrency Internals
Powershell – old tricks for a new dog?
Put Your Feet Up : Simplified Management using the Enterprise Policy Management Framework
Real World SQL Server High Availability
Report Builder 3
Self Service Business Intelligence- Project Gemini
Server consolidation with SQL Server
SQL 2008 Development Features
SQL Injection Attacks (and how to prevent them)
SQL Server 2008 - Unstructured Data Storage Solutions and Best practices
SQL Server optimization stuff you won’t find on Google (yet)
SQL, NoSQL, SomeSQL - A look at non-relational databases
SQLDataSources, LINQDataSources and EntityDatasources in Database Design
SSIS in SQL Server 2008
Strapped for cache? - Troubleshooting memory problems in SQL Server 2008
The R2 Duo: Running SQL Server 2008 R2 on Windows Server 2008 R2 Core
T-SQL Tuning with Colin Chapman, Enzo Ferrari, and The Stig
Using Perfmon and Profiler
Virtualising SQL Server
Vital Statistics
What's new in R2 for the DBA
When a query plan goes wrong

 

 

Dave has doe a couple of great posts on how Microsoft aren't adhering to best practices in there own products.

http://sqlblogcasts.com/blogs/sqlandthelike/archive/2010/01/25/microsoft-follow-best-practices-part-2.aspx

This is also related to the talk I'm giving at Developer Day on Entity Framework. The first version is shocking from a SQL perspective and really isn't fit for purpose. I'll be going into the details of what can happen and how to avoid them

http://developerdeveloperdeveloper.com/ddd8/Default.aspx 

 

Posted by simonsabin | 1 comment(s)
Filed under: ,

 

I am in the process of uploading all the SQLBits videos. They look great.

All the videos should be up by the end of the week.

As taster you can see my session here http://sqlbits.com/Agenda/event5/When_a_query_plan_goes_wrong/default.aspx

to watch in a local media player use this link http://sqlbits.com/information/Agenda/Video.ashx?SessionId=343&Regenerate=

or to download click here http://sqlsocial.com/videos/sqlbitsV/47%20When%20a%20Query%20Plan%20Goes%20Wrong_w.wmv 

 

 

Posted by simonsabin | 1 comment(s)
Filed under: , ,

 

I was asked by a client about the new Time datatype in SQL 2008. They wanted to store the duration of some work so they could use the nice date time functions to get the hours, minutes, seconds etc.

However you can't use the Time date type for that, because it can only hold time up to midnight after that it roles around to 0. Not much use if something takes longer than 24 hrs to run.

If you would like to have such a feature then vote for the reccomendation for an interval data type. https://connect.microsoft.com/SQLServer/feedback/ViewFeedback.aspx?FeedbackID=432281

If you can't wait until fro a nother 3 or 4 years then you could cheat.

If you use the datetime data type then you can add these together and get the behaviour you want. So you can get 04:53 and add it to 20:52.

To find the hours, months etc you perform a datedfif with 0. like this

declare @time datetime

set @time = cast('4:53' as datetime ) + cast('20:52' as datetime)

select DATEDIFF (minute,0,@time)

NOTE: You can't do this type of calculation with the new date and time data types you have to use the date add functions. This IMHO is one of the poor aspects of the new data types

 

 

I've been workig with XML in SQL Server Integration services this week and to say the XML task in SQL Server Integration services sucks is an understatement. Its buggy, the documentation is woefully inadequate in some cases wrong. I believe this was one of the first components written back for SQL 2005 so you can imagine it was written along time ago, XML wasn't as standardised.

So what if you want to validate an XML document against a XSD Schema. Well in true SQL Server Integration services mode the answer is to do it yourself with a script task.

There are two ways of doing it, the first uses an XmlDocument object and the other is the XmlReader. If you were on my XML course at SQLBits you will remember that I pointed out the importance of straeming when dealing with large data and this is where these two differ. The XmlDocument loads the document into memory, whereas the XmlReader is a streaming interface to the XML document you have. So if you have a large document you should use the XmlReader.

In my case however I wanted to pass the XML to a stored procedure after it had been validated and so I used the XmlDocument.

The first step is to create a XmlSchemaSet and put your schema into it.

string Filepath = Dts.Variables["User::FullNewFilename"].Value.ToString();

string Schema= Dts.Variables["User::SchemaFilepath"].Value.ToString();

 

// Create a schema set

XmlSchemaSet schemaset = new XmlSchemaSet();

// Add the schema to the collection.

schemaset.Add(XmlSchema.Read(XmlReader.Create (Schema),null));

Here Schema is a variable to the path for the schema and Filepath is the variable to the Xml file to be validated.

After that you have to either use the XmlDocument or XmlReader. For the XmlDocument we are passing back the contents of the file using the InnerXml property.

//clear our errors string builder

ValidationErrors = new StringBuilder();

 

//Use this if you need to read the document for use elsewhere

XmlDocument doc = new XmlDocument();

doc.Schemas = schemaset ;

doc.Load(Filepath );

doc.Validate(new ValidationEventHandler(ValidationCallBack));

           

//Load the contents of file into the variable for later processing.

Dts.Variables["ImportFileContents"].Value = doc.InnerXml;//clear our errors string builder

or use the XmlReader, this requires another object the XmlReaderSettings object

//set the validation settings.

XmlReaderSettings settings = new XmlReaderSettings();

settings.ValidationType = ValidationType.Schema;

settings.Schemas = schemaset ;

settings.ValidationEventHandler += new ValidationEventHandler(ValidationCallBack);

             

using (XmlReader xr = XmlReader.Create(Filepath,settings ))

{

    //This reads the whole document through the reader and does the validation

    while (xr.Read()) ;

 

    //Close the reader

    xr.Close();

}

In both you will see that they have references to the ValidationCallBack. The validation model is a callback model and so you need this extra function. This is why we are using a global variable ValidationErrors to store the errors and then be able to access them after the validation succeeds. The validation callback function is described here

// Display any validation errors.

private void ValidationCallBack(object sender, ValidationEventArgs e)

{

    ErrorOccurred = ErrorOccurred || e.Severity == XmlSeverityType.Error;

    Warning= Warning|| e.Severity == XmlSeverityType.Error;

 

    if (ValidationErrors.Length > 0)

    {

        ValidationErrors.AppendLine();

    }

    ValidationErrors.Append(e.Message);

}

Complete Code

So putting it all together we get

StringBuilder ValidationErrors;

bool ErrorOccurred= false;

bool Warning = false;

 

public void Main()

{

    string Filepath = Dts.Variables["User::FullNewFilename"].Value.ToString();

    string Schema= Dts.Variables["User::SchemaFilepath"].Value.ToString();

 

    // Create a schema set

    XmlSchemaSet schemaset = new XmlSchemaSet();

    // Add the schema to the collection.

    schemaset.Add(XmlSchema.Read(XmlReader.Create (Schema),null));

 

    //clear our errors string builder

    ValidationErrors = new StringBuilder();

 

    //Use this if you need to read the document for use elsewhere

    XmlDocument doc = new XmlDocument();

    doc.Schemas = schemaset ;

    doc.Load(Filepath );

    doc.Validate(new ValidationEventHandler(ValidationCallBack));

           

    //Load the contents of file into the variable for later processing.

    Dts.Variables["ImportFileContents"].Value = doc.InnerXml;

 

 

    /*  //Otherwise use the following

    // Set the validation settings.

    XmlReaderSettings settings = new XmlReaderSettings();

    settings.ValidationType = ValidationType.Schema;

    settings.Schemas = schemaset ;

    settings.ValidationEventHandler += new ValidationEventHandler(ValidationCallBack);

 

    using (XmlReader xr = XmlReader.Create(Filepath,settings ))

    {

        //This reads the whole document through the reader and does the validation

        while (xr.Read()) ;

 

        //Close the reader

        xr.Close();

    }*/

           

    if (ValidationErrors.Length > 0)

        Dts.Variables["XMLError"].Value = ValidationErrors.ToString();

 

    Dts.Variables["Validation"].Value = ErrorOccurred?"Error":(Warning?"Warning":"");

}

 

// Display any validation errors.

private void ValidationCallBack(object sender, ValidationEventArgs e)

{

    ErrorOccurred = ErrorOccurred || e.Severity == XmlSeverityType.Error;

    Warning= Warning|| e.Severity == XmlSeverityType.Error;

 

    if (ValidationErrors.Length > 0)

    {

       ValidationErrors.AppendLine();

    }

    ValidationErrors.Append(e.Message);

}

Enjoy.

 

More Posts Next page »