Do it, it’s important.
Ok, I suppose I should expand a bit upon that and in this case add an actual example.
So last night, I again attended the local SQL Server User Group meeting. The talk this month was by Ray Kim and was on Documentation for Techies. While we all agree that documentation is good, it’s sort of interesting how rare most techs actually do it. Ray’s talk covered some of this and further talked about exactly how valuable it is. In addition, several audience members spoke about how proper documentation saved their company a great deal of money simply by giving their tech support people the ability to answer questions in a far faster form.
I got thinking about some of the clients I’ve worked for and how I’ve wanted to document stuff, but often they have very little actually setup in the way of procedures to handle documentation. This is unfortunate, because it can cost them money. For example, for a client right now I’m working on automating a task. It turns out that there’s not much documentation, so I’m basically struggling to figure things out as a I go.
One thing you hear tech folks talk about a lot is “oh the code is self-documenting”. And sometimes it is. Since I work in SQL, often, but not always it’s clear what the code is doing. For example
Select firstname, lastname from Clients where ClientID=@ClientID
probably doesn’t need a comment saying what it does. It’s pretty clear. But a more complex query might need some commenting, or it may need some explanation as why a particular approach was taken. For example I was recently writing a stored procedure where the where clause was not quite what one would expect if one were to naively write it in the most obvious manner. However, the obvious manner would have resulted in a table scan of a very large table. By writing what I did, I could ensure a seek would occur.
I also had a habit, which after thinking about last night and testing today, I’m going to modify a bit. Often I’d write procedures such as:
-- Usage: Exec FOO -- Author: Greg D. Moore -- Date: 2016-03-15 -- Version: 1.0 -- This simply returns bar when executedif OBJECT_ID('foo', 'p') is not null drop procedure foo gocreate procedure foo asselect 'bar'go
Now, note technically this is a script (T-SQL) that will drop and then create the procedure, so it’s more than just the script. But it’s useful for me because I can ensure I’m running the latest and greatest and drop the old one if it exists before running it.
But, last not got me thinking. What happens if 3 years down the road someone comes along and needs to edit my code. Let’s say the client didn’t do a good job of keeping track of source code and they have to extract the scripts to create the procedures from SQL Server itself using say SSMS?
The results end up looking much more like this:
USE [Baz] GO/****** Object: StoredProcedure [dbo].[foo] Script Date: 03/15/2016 10:47:22 ******/IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[foo]') AND type in (N'P', N'PC'))DROP PROCEDURE [dbo].[foo] GOUSE [Baz] GO/****** Object: StoredProcedure [dbo].[foo] Script Date: 03/15/2016 10:47:22 ******/SET ANSI_NULLS ON GOSET QUOTED_IDENTIFIER ON GOcreate procedure [dbo].[foo] asselect 'bar'GO
Ignore the extra USE statements and the SSMS generated comments and SET statements. Notice my comments are gone. This actually makes sense because in the first script, the comments occur before a GO statement so the SQL engine interprets them as completely separate from the statements to create the actual stored proc. All my useful comments are now history.
BUT, there’s a simple solution. Move the comments to after the first GO statement.
if OBJECT_ID('foo', 'p') is not null drop procedure foo go -- Usage: Exec FOO -- Author: Greg D. Moore -- Date: 2016-03-15 -- Version: 1.0 -- This simply returns bar when executed -- Version: 1.1 -- Comments moved below GO statement create procedure foo as select 'bar' go
Now if I use SSMS to generate my script I get:
USE [Baz]
GO/****** Object: StoredProcedure [dbo].[foo] Script Date: 03/15/2016 10:48:53 ******/
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[foo]’) AND type in (N’P’, N’PC’))
DROP PROCEDURE [dbo].[foo]
GOUSE [Baz]
GO/****** Object: StoredProcedure [dbo].[foo] Script Date: 03/15/2016 10:48:53 ******/
SET ANSI_NULLS ON
GOSET QUOTED_IDENTIFIER ON
GO— Usage: Exec FOO
— Author: Greg D. Moore
— Date: 2016-03-15
— Version: 1.0
— This simply returns bar when executed
— Version: 1.1
— Comments moved below GO statementcreate procedure [dbo].[foo]
asselect ‘bar’
GO
Now my great documentation is preserved. This is a small thing but down the road could save the next developer a lot of trouble.
So, stop and think about not only documentation, but how to make sure it’s preserved and useful in the future.