Unfortunately, it has been awhile since I have posted a blog up here, but having spent several hours last night on Twitter with a number of esteemed members of the SQL Server community trying to educate a blogger, John Dunleavy [Twitter/Blog] about the proper way to credit authors when you use their work inspired me to get this post up.  Unfortunately, the issue of bloggers or web site operators using other people’s work without properly crediting them is becoming an increasingly more frequent occurrence.  Earlier in the day yesterday, Aaron Bertrand [Twitter/Blog] had a very similar issue with a SQL Server MVP (you can read Aaron’s blog post and the associated comments here). 

So, the point of my post today is not really to rehash the issue of plagiarism (intended or unintended), but rather to discuss why most of us give back to the community in the form of informative blog posts, volunteerism, and answering questions on the forums and to extend that a little bit, if I may, by offering the services and knowledge of the SQL Server community to educate new bloggers about how to get started, what is acceptable, and what is not.

 

First off, why do we do what we do?  Speaking for myself and,  I think,  many members of the SQL Server community, we do this because a) we were all in a position where we were just starting out and needed help; b) someone helped us, answered our questions, and we feel honored to be able to do the same; c) we take great pride in having one of the most open, collaborative, and philanthropically motivated communities in the world of technology.  These services are provided free of charge to anyone who visits any of the hundreds of great SQL Server blogs out there.  The number of books that you would have to purchase or expensive courses that you would have to attend to get anywhere near the content that is freely available on blogs in the SQL Server community would set you back many, many thousands of dollars and it still wouldn’t provide you with all of the benefit of the experience that this community writes from.  Through our discussions last night, some barbs were thrown our way such as “how can you help if your[sic] linin[sic] your pockets” and “You guys are being selfish.”  I would like to address those as I believe there must be a huge misconception about the motivation behind what we do.  First off, there is “no pocket lining” going on here.  Speaking for our site, http://sqlservertimes2.com, we pay for the domain registration and hosting out of our own pockets which, in my eyes, is an investment back into the community.  We receive no revenue from our site as there is no advertising or services sold from the site.  Now, that is just our choice and I want to be clear that there is absolutely nothing wrong with hosting ads offering services from your site, if you so choose, to help pay the bills, as long as the content of your site is original or you have at least obtained the permission of the original authors or copyright owners to host non-original material.  Our motivation is strictly a collaborative one.  Lori and I post issues that we have come across in our jobs and the solutions that we have come up with to solve them.  Throughout our careers, we have relied heavily on others’ blog posts for our professional development and feel honored to now be able to participate in that and provide something back.  Our compensation is solely the feedback we receive from readers that lets us know that we provided something that saved someone some time somewhere down the road, nothing more, nothing less.

 

So, where does this leave us?  As I have said many times, I think the SQL Server community is one of the greatest technical communities around.  One of the main reasons for this is the lack of egos and willingness to share.  The majority of us are not insecure and welcome new bloggers with open arms because all of us are constantly learning.  If a day goes by where I haven’t learned something new, it was not a very good day in my book and the more people out there sharing knowledge, the more likely I am to learn something new.  This is a very forgiving community and I believe that if you are a blogger who has or is plagiarizing the work of others because, for some reason, you didn’t realize that it was wrong or you don’t know how to get started blogging, reach out to the community and ask for help.  There are many of us who will gladly help you start sharing your own knowledge and gifts with the community, all you have to do is be willing to understand that plagiarism is stealing and wrong and be open to feedback from the group.  I know most technical professionals are proud and do not like to admit being wrong, but  many times being wrong is the first path to learning.

I was tagged by TJay Belt (Twitter/Blog) in this latest series of blog stories.  I believe that it was started by Paul Randal (Twitter/Blog), carried on by Tom LaRock (Twitter/Blog) and then went viral.  Since ‘New Year’ seems to be synonymous with ‘everything going to heck in a handbasket’, it’s taken me awhile to respond, but here goes.

 

I’ll start by saying that if anyone would have told me that I’d be a DBA (or anything computer related for that matter)

You may ask yourself, well, how did I get here?

You may ask yourself, well, how did I get here?

when I was in college, I would have fallen down laughing.    My step-father was a biomechanical engineer and one of my main goals in life was not to be a geek like I thought he was.  I majored in Communications with a minor in English.   At the time of my

graduation I had never touched a computer or even wanted to.  So, how did I get to be a DBA?  Sheer coincidence.

 

IBM

Back in my kid-free days, I worked for IBM.  I actually had to use a computer (odd for me), but my responsibilities were working with IBM’s resellers and the maintenance plans they resold.  It was all about soft skills and I spent a ton of time on the phone with resellers.  All of the information that we gathered was stored in a(wait for it…) DB2 database.   After awhile, I took on the responsibility for putting together reports.  While there was definitely no administration going on, it was kind of fascinating to play with all of that data.  That all stopped, though, for my next life changing event.

 

And they looked so sweet...

And they looked so sweet...

Kids

I left my job at IBM just before I gave birth to my first child and became a stay-at-home mom.  Around the time my

 second child was born, I started to feel the desire to go back to school.  The odd thing is that the field that I was drawn to was computer science.  I’m not sure if it was due to some strange chemical imbalance or the need to spend time with something that actually had logic behind it, but I began my computer science degree shortly after my youngest son turned one. 

Going back to school with two little ones running around was definitely a challenge.  Getting to the end of an 800 line assembly language project and have my son smack his hand on the keyboard deleting it, helped me learn the value of saving and saving often.  I’m sure that trying to learn recursion while dealing with a cranky toddler helped my ability to persevere.   Eventually, though.  I completed the program and became a computer science instructor.  Teaching was and is still the field that provides me with the greatest amount of satisfaction.  I enjoyed it immensely and felt that I was good at it.  Unfortunately, though, by that time I was a single mother of two boys and job satisfaction doesn’t exactly pay the bills.

 

My first *real* job

After leaving my teaching position at the college, I was able to get a job teaching the medical staff at our local hospital the new order entry/documentation application.   I knew that this had to be temporary and that I needed to become a part of a more technical division.  During the process of keeping our training environment up to date, I ended up interfacing with our DBA group on a regular basis.  One of the DBAs left and that provided me the opportunity to join the team.   Our lead DBA was pure awesomeness and provided me with a good solid platform of knowledge.  That was back in 2003, completed my MCDBA in 2005 and the rest is, well, the rest is now.    Still working, still learning.

 

It was a crazy, twisted road to get here and I’m looking forward to the road ahead.  I’m not tagging anyone with this, but I’m thankful to TJay for giving me the chance to share my story.

Several weeks ago on Twitter, Colin Stasiuk (BlogTwitter), ) asked if anyone had a script to pull back job statuses from the SQL Server Agent.  I had been doing some work on a SQL Server DBA Console and had written some PowerShell scripts to give me various pieces of information and put together a PowerShell script that could be run as a SQL Agent job to periodically report the statuses of SQL Agent jobs.  Eventually, I think Colin went with a different solution, but I figured I would go ahead and post the PowerShell script that I came up with.  This solution has been tested against SQL Server 2000/2005/2008.

 

This first script is just a SQL script to create the SQL Server table that the PowerShell script writes the status information to and can be downloaded here, LastJobStatus_Table.sql.

CREATE TABLE [dbo].[LastJobStatus](
	[ServerName] [nvarchar](128) NULL,
	[Job_Name] [nvarchar](128) NULL,
	[Run_Date] [datetime] NULL,
	[Job_Duration] [time](7) NULL,
	[Run_Status] [varchar](50) NULL,
	[Sample_Date] [datetime] NULL
) ON [PRIMARY]

 

The next is the PowerShell script that does all of the work bringing back the SQL Agent job statuses.  It takes a parameter of Server, which is the name of the SQL Server that you want job statuses from.  Make sure that you change the name “MgtServer” to whatever the name is of the SQL Server where you intend to store the results from this script.   You’ll also need to change the root directory for where your scripts are loaded to match your environment. This script can be downloaded here, Get-LastJobStatusServer.ps1.

param([string]$Server=$(Throw "Parameter missing: -Server ServerName"))
[void][reflection.assembly]::LoadWithPartialName("Microsoft.SqlServer.Smo")

##Point to library files
$scriptRoot = "D:\DBAScripts"

--change script root directory to match your environment
#$scriptRoot = Split-Path (Resolve-Path $myInvocation.MyCommand.Path)
. $scriptRoot\LibrarySmo.ps1	#Part of Chad Miller's SQLPSX project on CodePlex
. $scriptRoot\DataTable.ps1	    #Included with the scripts for this blog, also from a CodePlex project (http://www.codeplex.com/PSObject)

Set-Alias -Name Test-SqlConn -Value D:\DBAScripts\Test-SqlConn.ps1

##Define variables

## open database connection
$conn = New-Object System.Data.SqlClient.SqlConnection("Data Source=$server;
Initial Catalog=master; Integrated Security=SSPI")
$conn.Open()
$cmd = $conn.CreateCommand()
$cmd.CommandText= "	CREATE TABLE #JobsRun (	ServerName nvarchar(128),
											Job_Name nvarchar(128),
											Run_Date datetime,
											Job_Duration time(7),
											Run_Status varchar(50),
											Sample_Date datetime
										  );
					insert into #JobsRun
					select	@@SERVERNAME AS ServerName
							,j.name Job_Name
							,(msdb.dbo.agent_datetime(jh.run_date,jh.run_time)) As Run_Date
							,substring(cast(run_duration + 1000000 as varchar(7)),2,2) + ':' +
									substring(cast(run_duration + 1000000 as varchar(7)),4,2) + ':' +
									substring(cast(run_duration + 1000000 as varchar(7)),6,2) Job_Duration
							,case when run_status = 0
										then 'Failed'
								when run_status = 1
										then 'Succeed'
								when run_status = 2
										then 'Retry'
								when run_status = 3
										then 'Cancel'
								when run_status = 4
										then 'In Progress'
							end as Run_Status
							,GETDATE() As Sample_Date
					FROM msdb.dbo.sysjobhistory jh
						join msdb.dbo.sysjobs j
							on jh.job_id = j.job_id
					where	step_id = 0
					and		enabled = 1
					order by cast(cast(run_date as char) + ' ' +
								substring(cast(run_time + 1000000 as varchar(7)),2,2) + ':' +
								substring(cast(run_time + 1000000 as varchar(7)),4,2) + ':' +
								substring(cast(run_time + 1000000 as varchar(7)),6,2)  as datetime) desc

					delete from MgtServer.DBA_Console.dbo.LastJobStatus where ServerName = '$server'                       -- Change 'MgtServer' to the name of whatever the SQL Server is in
                                                                                                                                               -- your env that will house the LastJobStatus table which stores the
                                                                                                                                               -- results of this script
					insert into MgtServer.DBA_Console.dbo.LastJobStatus (ServerName, Job_Name, Run_Date, Job_Duration, Run_Status, Sample_Date)
					select	jr.ServerName,
							jr.Job_Name,
							jr.Run_Date,
							jr.Job_Duration,
							jr.Run_Status,
							jr.Sample_Date
					from	#JobsRun jr
					where	Run_Date = (	select	max(jr1.Run_Date)
											from	#JobsRun jr1
											where	jr1.Job_Name = jr.Job_Name)
					drop table #JobsRun; "
$cmd.ExecuteNonQuery()
$conn.Close()

 

There are references in the above script to a LibrarySMO.ps1 script that can be obtained from CodePlex (see the comments in the script for URL) and a DataTable.ps1 script (also from CodePlex, but included in the download file for this blog, for your convenience.)

# Taken from out-dataTable script from the PowerShell Scripts Project
# http://www.codeplex.com/PsObject/WorkItem/View.aspx?WorkItemId=7915

Function out-DataTable {

  $dt = new-object Data.datatable
  $First = $true  

  foreach ($item in $input){
    $DR = $DT.NewRow()
    $Item.PsObject.get_properties() | foreach {
      if ($first) {
        $Col =  new-object Data.DataColumn
        $Col.ColumnName = $_.Name.ToString()
        $DT.Columns.Add($Col)       }
      if ($_.value -eq $null) {
        $DR.Item($_.Name) = "[empty]"
      }
      elseif ($_.IsArray) {
        $DR.Item($_.Name) =[string]::Join($_.value ,";")
      }
      else {
        $DR.Item($_.Name) = $_.value
      }
    }
    $DT.Rows.Add($DR)
    $First = $false
  } 

  return @(,($dt))

}

Going with your gut

11 January 2010

This post is a response to Tim Ford’s Whose Blog Is It Anyway  challenge.  The opportunity to use the words: pony, nude and bong in a blog post about an actual experience was too much to pass up.

 

I’m a DBA and I’m logical – coldy logical, if you listen to K. Brian Kelley - but I’m here to tell you that sometimes you just have to go with your gut.  Most of us have an inner voice that clues us in on the things that you know but can’t rationalize or aren’t ready to deal with yet.  That’s the voice that lets you know that the URL in your son’s internet history with the word ‘PussyCat’, probably isn’t a site featuring live, nude cats.  Not everyone trusts that voice – just ask George “Let’s Have Padme Die Of A Broken Heart Instead Of Anakin Crushing Her To Death” Lucas – that would have been a far more awesome scene.

 

I’m here to talk about such a time, early in my career.   I had a great DBA to learn from, but he had moved on to another position.  I felt pretty firm in my knowledge and knew that, whatever came up I could fix or handle by simply using some magical tool, library or bong.

 

That’s when I ran into it – the problem that I couldn’t fix, but was going to cause me pain.  On a Friday evening I started seeing error messages in the SQL Server error logs that indicated that we were having disk issues.  Of course the error message didn’t read ‘Your disks are failing’, but everything that I was reading seemed to indicate that.  One thing that bears noting – this was the central order entry/documentation application for the hospital that I worked at – there was no acceptable downtime.  I contacted our system administrator who did some research and let me know that all of the disks looked fine.  Now, this was an SA whose knowledge I respected – he’d been in the field forever (not like ENIAC forever, but pretty close).   He alluded to the fact that I was still a newbie and probably didn’t diagnose the problem correctly.  At this point it was around noon on Saturday and even though I was getting tired of looking around, I figured that I’ve started, so I’ll finish.  I wasn’t able to find any information that was clearer than I had provided before, but I knew, in my gut, that we were about to have problems – big problems.  I called the SA again and tried to encourage him to look a little more closely.  I asked him to pretend that the RAID array was a horse stable.  From the outside, it might sound pretty happy.  On the inside it might look good initially, but as soon as he looks down he’s going to be very sad about the pony.  For some reason, that analogy didn’t work…

 

As the afternoon progressed, I kept with my gut feeling and bugged the heck out of that SA.  The disks actually gave up the ghost and 40 hours later (non-stop), with our application vendor and Microsoft on the line, we finally got the disks replaced and the application back online.  At the post-mortum, once everyone had gotten a few hours sleep, that same SA wanted to know how I knew what the problem was since none of the errors were absolutely clear about the cause.  I just told him that I knew in my gut that something bad was about to happen.  He said, “Well, if you’d told me that in the beginning, I would have done more research!”.

 

While the story above is true, some of the particulars have been changed to protect the innocent.

 | Posted by tledwards | Categories: Administration, DBAs, Uncategorized | Tagged: , , |

I was tagged by Jorge Segarra (BlogTwitter) who had been tagged by Thomas LaRock (BlogTwitter) in his post about his goals and themeword for 2010.  I was going to try to remain blissfully ignorant about being tagged, but then Tim went and posted his goals.  So I guess I’m on the line now.  My theme word for this year is:

 

Recharge

While there are many things that I want to accomplish this year, I don’t know that (m)any of them will occur until I can figure out a way to recharge.  I’m typically a self motivated type of person, but it seems like, during the previous year, I’ve hit the wall.

 

I’m not entirely sure what has caused this, but I’m guessing that it is some combination of the cyclical nature of job satisfaction, having a boatload of things going on at home and the disconnect between the amount of things that I would like to learn and the amount of free time that I have.

 

recharger

Is there a human connector on that thing?

I realize that there is no magic button that will instantly recreate the hunger for knowledge that I had when I began learning to be a DBA.  What I can do, though, is set some goals, work hard to follow through on them and be patient.   My hope is that in the process of achieving these goals, I’ll rejuvenate my love of this career path.

 

Goals

Pick one or two topics to focus on

I have at least three SQL Server books sitting on my desk and more at home that I haven’t done much more than flip through.  Rather than setting a goal to read all 3000 pages (doable, but daunting), I’m going to pick a couple of subjects to focus on and learn them as thoroughly as possible.  This is ongoing – if it’s March and I know everything there is to know about database corruption (or whatever it is I end up focusing on), I’ll move on to the next subjects.

 

Blog more

My first love is teaching.  It invigorates me and gives me purpose.  Blogging provides me an arena to hopefully teach people that are learning to be DBAs and the chance to share what I’ve learned.

 

Become more involved with PASS

As I’ve mentioned in previous posts and as Tim mentioned in his goals for 2010, we’ve talked often about starting a PASS chapter in Tucson.  This ties into my love of teaching and will help us to connect with folks locally who have similar interests.  I would also like to take part in other committees within PASS as needed.    This will definitely require a balancing act with work and family, so I’ll be taking baby steps to ensure that I don’t shortchange other areas in my life.

 

What does this all mean?

None of these individual goals are earth-shattering and that’s intentional.  I have a tendency to swing for the bleachers, but end up hitting to the pitcher and it makes me grumpy.  My hope here is that I make some good, solid line drives and then I’ll be set up to hit it out of the park.

 

I’m tagging a couple of people that have unknowingly helped me to recharge (some thank you, eh?) 

TJay Belt (BlogTwitter)

Wendy Pastrick (BlogTwitter)

Kendal Van Dyke (BlogTwitter)