SQL Login / Agent Jobs Ownership SNAFU

Late last night, I got the call that no DBA wants to get.

 

“Our Data Center has crashed”

 

It appears, both controllers in the VM Ware SAN crashed at the same time bringing every VM server down. Once the controllers were replaced, servers were brought back online. But that’s not the real point of this article, it is just the background of what happened.

SQL Logins

Typically when I install a SQL server, I use a domain Security Group as the Sys Admin.  Members of this group include myself, my monitoring service account and domain admins.  Because I am a member of this group, I typically remove my individual login.  This has not been an issue until last night; well really this morning.

SQL Agent Jobs

I had SQL Agent jobs failing all over the network once my servers were back up and running from the earlier crash and I couldn’t figure out why.

Message
The job failed.  The owner () of job SystemDB.Backup-Full does not have server access.

The owner()…does not have server access.  Why did it not list the owner?  Is there an owner?

I understand the importance of having non-domain accounts “owning” SQL Agent jobs; now more than ever.  As much as I try to replace myself as job owner when I edit a job; it just sometimes slips my mind.

Every job owned by my network account was failing across the company. When researching I tried to get a listing of all jobs and their owners using the script below; but not all the jobs were listed.  Why weren’t all jobs being listed?

SELECT

    j.job_id

    ,j.name

    ,l.name

FROM msdb.dbo.sysjobs j

INNER JOIN master.sys.syslogins l

ON j.owner_sid=l.sid

Digging deeper, I remembered that syslogins is actually a view of sys.server_principles.  Reading the entries there, my network login was not a principle which made sense because I removed my network login principle.  But my login was a job owner; apparently SQL will use the current logged in user as the new owner ever if it is not a principle. I tested this by removing my login from a test server, creating a new job and there she blows!

server_principle

So, I wanted needed a quick way to change job ownership of all SQL Agent Jobs. So I developed the following script. 

DECLARE @jobID UNIQUEIDENTIFIER

DECLARE @job_owner VARCHAR(50),@job_name VARCHAR(150),@login_name VARCHAR(150)

 

DECLARE jobs CURSOR FOR

SELECT

    j.job_id

    ,j.name

    ,l.name

FROM msdb.dbo.sysjobs j

INNER JOIN master.sys.syslogins l

ON j.owner_sid=l.sid

WHERE l.name <>'sa'

 

OPEN jobs FETCH NEXT FROM jobs INTO @jobID,@job_name,@login_name

WHILE @@FETCH_STATUS =0

BEGIN

    DECLARE @run INT

    PRINT 'Changing ' + @job_name + ' owner from ' + @login_name + ' to [sa]'

    EXEC @run = msdb.dbo.sp_update_job @job_id=@jobID,@owner_login_name=N'sa'

    IF @run=0

        BEGIN

        PRINT 'Success: ' + @job_name + ' owner was changed to [sa]'

        END

        ELSE IF @run <> 0

        BEGIN

            SELECT 'Fail: ' + @job_name + ' owner was not changed'

        END

    FETCH NEXT FROM jobs INTO @jobID,@job_name,@login_name

END

CLOSE jobs

DEALLOCATE jobs

 

SELECT

    j.name

    ,j.enabled

    ,l.name

FROM msdb.dbo.sysjobs j

INNER JOIN master.sys.syslogins l

ON j.owner_sid=l.sid

This script will be added to my “toolbox” for sure. I may set this up as a SQL Agent job itself randomly checking, or maybe a SSIS package using @Variables for Server Names, but for now, I will manually run this on severs that need it.

Lesson Learned!

SQL Development Tools–I need what version?

Being a SQL DBA and part time SSRS developer, I sometimes get very confused and lost in what version of BIDS  or SSDT (SQL Server Data Tools) I need for what version of SQL. And now it seems SSDT is different from SSDT-BI (SQL Server Data Tool for Business Intelligence)  So, I am writing this blog as a reminder and starting point to determine what I need to tell colleagues what to download when setting up a new developer’s desktop with the right tools for the right job. I also want to be able to know what exactly will be installed on the machine for the developers.

My inventory of SQL Servers range from 2000 (yes I still have 2 instances of SQL 2000 in production, but that’s for another blog post) through 2014!  My “shop” primarily uses SSIS and SSRS with our SQL Servers so that is all I am confident with.

The below information goes under the assumption you do not have any retail version of Visual Studio installed on your computer. And with that assumption, all of the downloads will install a Visual Studio Shell IDE for use in your development.

Database Development (with scripting, deployment and Source Control)

SQL 2005 & 2008 — SQL Server Data Tools (SSDT) for Visual Studio 2010

SQL 2012 & 2014 — Visual Studio 2012 & 2013 (Built in support)

SSRS Development

SSRS 2005 — BIDS 2005 (Visual Studio 8)

SSRS 2008 — BIDS 2008 (Visual Studio 9)

SSRS 2008 R2 — SQL Server Data Tools for Visual Studio 2010

SSSRS 2012 & 2014 — SQL Server Data Tools for Visual Studio 2010 and SQL Server Data Tools for Business Intelligence (SSDT-BI) for Visual Studio 2012 or Visual Studio 2013

SSIS Development

SSIS 2005 — BIDS 2005 (Visual Studio 8)

SSIS 2008 — BIDS 2008 (Visual Studio 9)

SSIS 2008 R2 — SQL Server Data Tools for Visual Studio 2010

SSIS 2012 & 2014 — SQL Server Data Tools for Visual Studio 2010 and SQL Server Data Tools for Business Intelligence (SSDT-BI) for Visual Studio 2012 or Visual Studio 2013


Well, I hope I didn’t mess those up. I sure wish Microsoft would get SQL Server, SSDT and SSDT-BI all on the same numbering system!  I can never remember which version of Visual Studio to launch for which version of SQL; maybe this reference will help!

Is a Deprecated feature making my job more difficult?

By definition, a “deprecated” feature refers to a feature or specific function in a piece of software that will be replaced with a newer function/feature or just flat out will be no longer available.

Microsoft is notorious for changing and/or removing features in every version of SQL!  SQL 2014 has an extensive list of deprecated features: https://msdn.microsoft.com/en-us/ms143729.aspx.

The one I found out about today is SET FMTONLY (format only).  This particular setting allows a stored procedure to return the format of the results without actually returning results. This feature has been available since SQL 2005 and apparently will be removed from a future version, to be determined later.

   1: USE AdventureWorks2012;

   2: GO

   3: SET FMTONLY ON;

   4: GO

   5: SELECT * 

   6: FROM HumanResources.Employee;

   7: GO

   8: SET FMTONLY OFF;

   9: GO

In my line of work, I do a lot of SSIS packages that export information to flat files.  And my developers use temp tables religiously.  The problem with this, SSIS packages typically have a problem with resolving the columns of the final result set from a stored procedure when temp tables are used.  The use of SET FMTONLY OFF allows the SSIS package to resolve the stored procedure without attempting get the column definitions first so the statements can complete, which in turn presents the SSIS Data Source with the final column definition.

Beginning in SQL 2012 two new features were debuted to replace FMTONLY setting.

sp_describe_first_result_set Returns the metadata for the first possible result set of the Transact-SQL batch.

   1: sp_describe_first_result_set [ @tsql = ] N'Transact-SQL_batch' 

   2:     [ , [ @params = ] N'parameters' ] 

   3:     [ , [ @browse_information_mode = ] <tinyint> ] ]

sys.dm_exec_describe_first_result_set This dynamic management function takes a Transact-SQL statement as a parameter and describes the metadata of the first result set for the statement

   1: sys.dm_exec_describe_first_result(@tsql, @params, @include_browse_information)

Why 2 you ask?  I have no clue.  These two seem to do the same thing, not sure why two different ways to do the same thing, but I digress…

The point of this article is now when I create a stored procedure with temp tables for an SSIS package, I have to pass the T-SQL statements as a parameter into these function first then execute the T-SQL statements.

Maybe I am too much of a novice, but to take a stored procedure with several hundred lines of code and turn it into a variable @tsql, then pass that variable into a function just to get column definition, then EXEC @tsql sounds more difficult than simply typing SET FMTONLY OFF; Apparently smarter people than me have decided this is the best way to do this.

Of course by accident, I discovered another, almost as simple, solution for SSIS packages and temp tables.  Instead of using a temp table, define a Table Variable at the beginning of the stored procedure.  This @TableVariable will be your final result set, insert records into this table. Using this method, your stored procedure can still use temp tables and have a defined result set for the SSIS data source. 

So, to answer the original question:  Is a deprecated feature making my job more difficult? 

Well, Yes and No.  Yes, because I believe the replacement feature is more difficult to execute and write code for, especially when your stored procedure has multiple statements.  And adding more steps to an already lengthy process is never a good thing. 

And No, because I found a just as easy useable solution with table variables. I just switch # for @ and define my columns.  easy as 1…2…3!

MCSA: SQL 2008

After a couple of tries (finding time to study is harder than I thought), I have finally passed my 70-432 to earn my Microsoft Certified Solutions Associate SQL 2008!  Having previously earned my MCTIP: SQL Server 2008 Business Intelligence, I only needed this one test.

Now, I must crack down!  I will study, break, fix and torture a SQL Development server for my 70-457 and 70-458 to transition to SQL 2012!

I know some people in the SQL world do not see certifications as all that necessary and definitely not completely indicative of real world experiences; but this was a personal/professional goal of mine to earn my MCSA SQL 2012.  I am now 2 tests away!

Who knows, I may go for my MCSE!