Av rating:
Total votes: 111
Total comments: 54


Robert Sheldon
Transact-SQL Formatting Standards (Coding Styles)
25 August 2009

How should SQL code be formatted? What sort of indentation should you use? Should keywords be in upper case?  How should lists be lined up? SQL is one of those languages that will execute however you treat whitespace and capitalization. However, the way SQL is laid out will effect its readability and the time taken to review and understand it. Standardisation of code layout is an important issue, but what standard should you adopt? Rob avoids a direct answer, but tells you the sort of answers you'll need to decide upon when creating a strategy for formatting SQL code.

Few topics generate as much debate among database engineers as how Transact-SQL code should be formatted. For every issue raised, you’ll likely receive twice as many opinions as there are people. Yet standardizing the T-SQL code across an organization is essential to facilitating effective and efficient code reviews, troubleshooting T-SQL script, supporting joint development efforts, and handing off projects from one group to another. DB engineers might disagree about what the code should look like, but few will question the wisdom of implementing such standards.

Yet as anyone knows who’s participated in this process, it’s no small task. And the more DB folks involved, the more Herculean the project. But you’ve got to start somewhere, and that’s what this article is all about—to provide you with an outline of the types of decisions you’ll need to make when trying to standardize your code’s format. Whether you’re working with beautification software such as the Format SQL feature included in Red Gate’s SQL Prompt or formatting all your code manually, you need to take into account a variety of factors when determining how to style your T-SQL script.

A word of warning, however. This is not a discussion about optimizing your code, maximizing performance, or determining what policies to implement to address such issues as indexing, using GUIDs as primary keys, whether to store BLOB content, how to set security policies, and so on. Of course, these are all important considerations, but they’re not what we’re focusing on here.

In fact, because of the volatile nature of discussions about formatting, I will try to hold back on my opinions altogether, and instead focus on the issues themselves, and not their resolution. The final decisions about how you format your code are up to you. What I plan to provide here are the questions you should ask yourself as you’re mapping out your formatting strategy. I also provide examples that demonstrate different ways you can format your code.

Case (Capitalization)

Case refers to the way in which T-SQL should or should not be capitalized in your code. For example, some developers prefer to make all reserved keys uppercase, others prefer lowercase, and some mix and match. It’s all a matter of preference. When determining what strategies to implement with regard to case, you should take into account the following considerations:

  • How should you categorize Transact-SQL in terms of keywords, data types, user-defined objects, etc.? For example, should all reserved words be treated as one category, or do you prefer to treat data types differently from other keywords? What about user-defined objects, such as tables and views? Some sources break this category down into scalars (columns, parameters, variables) and schema objects (tables, views, stored procedures). Others make no distinction and treat all T-SQL elements as a single category.
  • What case rules will you apply to each category? For example, should keywords be all uppercase, and data types all lower case? Should you use camel case (compound words with an initial capital) for user-defined objects such as table names?

Let’s look at some examples that demonstrate different capitalization strategies. In the first statement, all T-SQL reserved words are uppercase, but user-defined object names, such as tables and columns are camel case, with the first letter capitalized:

IF OBJECT_ID(‘ProductDocs’, ‘U’) IS NOT NULL

DROP TABLE ProductDocs

GO

CREATE TABLE ProductDocs

(

  DocID INT NOT NULL IDENTITY,

  DocTitle NVARCHAR(50) NOT NULL,

  DocFileName NVARCHAR(400) NOT NULL,

  CONSTRAINT PK_ProductDocs_DocID PRIMARY KEY CLUSTERED (DocID ASC)

)
GO

In the next example, all the reserved words are lowercase, and the user-defined object names are camel case:

if object_id(‘ProductDocs’, ‘U’) is not null

drop table ProductDocs

go

create table ProductDocs

(

  DocID int not null identity,

  DocTitle nvarchar(50) not null,

  DocFileName nvarchar(400) not null,

  constraint PK_ProductDocs_DocID primary key clustered (DocID asc)

go

Here’s one other example. This time, the keywords are uppercase, the data types lowercase, and the object names camel case:

IF OBJECT_ID(‘ProductDocs’, ‘U’) IS NOT NULL

DROP TABLE ProductDocs

GO

CREATE TABLE ProductDocs

(

  DocID int NOT NULL IDENTITY,

  DocTitle nvarchar(50) NOT NULL,

  DocFileName nvarchar(400) NOT NULL,

  CONSTRAINT PK_ProductDocs_DocID PRIMARY KEY CLUSTERED (DocID ASC)

)

GO

The key to a capitalization strategy should be readability. There’s no real right or wrong, as long as the standards are applied consistently throughout the organization (and you’re consistent with the collation of the identifiers used in the target databases).

Object References

When you reference an object such as a table or column, you must decide about such issues as whether to qualify the object name, whether wildcards are permitted, and so on. The following questions provide an outline of the types of details you should take into account when deciding how to reference objects:

  • How extensively should you qualify object names? For example, should you always include the schema name with a table even if the schema is dbo? Should you include the database name as well?
  • Do different types of code call for different naming strategies? For instance, should you reference objects in a stored procedure differently from how you would reference objects in a data definition language (DDL) statement?
  • Is the asterisk (*) wildcard permitted in SELECT lists rather than specifying the column names? Are there circumstances when a wildcard would be permitted? Although most guidelines recommend against using the wildcard in a SELECT list, you cannot assume that everyone follows these guidelines. For this reason, you need to be very specific about these sorts of style decisions.
  • Should column names always be specified in INSERT and UPDATE statements? For some of these statements, it’s not necessary to include the column names, but best practices generally recommend that you do include them. As with the use of wildcards in SELECT lists, you should be very specific.
  • Is the use of column numbers in place of names permitted in your T-SQL statements? For example, you can use column numbers in the ORDER BY clause when referencing columns in the SELECT list.

Let’s take a look at a few examples that demonstrate some of these issues. In the first example, a wildcard is used in the SELECT list, in place of the column names:

SELECT * FROM ProductDocs

Now compare this example to the following example, which specifies the column names in the SELECT list:

SELECT DocID, DocTitle

FROM AdventureWorks.dbo.ProductDocs

Clearly, there’s no doubt which columns should be retrieved. Even if new columns are added to the table, the code will still work. Notice also in this example that the table name is qualified with the database and schema names. Again, you must decide how to handle these sorts of issues. Now take a look at an example that includes an ORDER BY clause. In this case, the clause uses an integer to refer to the DocTitle column, the second column in the SELECT list:

SELECT DocID, DocTitle

FROM AdventureWorks.dbo.ProductDocs

ORDER BY 2 DESC

Most best practices guidelines recommend against using the integer in this way, but like the use of the wildcard in the SELECT list, it’s still done. In the next example, the ORDER BY clause specifies the column name:

SELECT DocID, DocTitle

FROM AdventureWorks.dbo.ProductDocs

ORDER BY DocTitle DESC

As you can see in this example, the SELECT list includes the column names, rather than a wildcard, the table name is qualified with the database and schema names, and the ORDER BY clause contains the column name. Your standards must be very specific about all these types of issues and not assume anything.

Now let’s take a look at another issue. In the next example, an INSERT statement adds data to the ProductDocs table without specifying the column names:

INSERT dbo.ProductDocs

VALUES ('Test1.doc', 'C:\Files\Test.doc')

Depending on the table definition, you can often insert data without specifying the columns. However, if the table definition should change, this statement would fail. For that reason, best practices guidelines often specify that the column names should be included, as the in following example:

INSERT dbo.ProductDocs (DocTitle, DocFileName)

VALUES ('Test2.doc', 'C:\Files\Test.doc')

Notice in the last two examples that the table name has been qualified with only the schema name. Again, this is a decision that you’ll have to make when you define your policies about calling objects.

Aliases

Aliases let you assign temporary names to objects (or assign names to computed columns) so they’re easier to work with when writing and reviewing code. When determining what strategies to employ for aliases, you should take into account several considerations:

  • Will you implement a different strategy for different alias types? For example, should table aliases be treated the same as column aliases? Should all column aliases be treated the same, or should computed columns be treated differently from renamed columns?
  • What types of alias names are permitted? Can single letters be used for table aliases? Can abbreviations be used for any type of aliases? Should column aliases follow the same naming conventions as those used for object names?
  • Should the AS keyword always be used? Never used?

In the following example, the column alias (FullName) is a compound word, but the table aliases are single letters:

SELECT

   (c.FirstName + ' ' + c.LastName) AS FullName,

   e.LoginID, e.Title

FROM HumanResources.Employee AS e

   INNER JOIN Person.Contact AS c

   ON e.ContactID = c.ContactID

ORDER BY c.LastName

In complex joins, single-letter aliases can sometimes make the code more difficult to follow because it’s not always intuitive which columns are associated with which tables. The following example uses more meaningful abbreviations for the table aliases:

SELECT

   (cnt.FirstName + ' ' + cnt.LastName) FullName,

   emp.LoginID, emp.Title

FROM HumanResources.Employee emp

   INNER JOIN Person.Contact cnt

   ON emp.ContactID = cnt.ContactID

ORDER BY cnt.LastName

Notice the use of the AS keyword in the last two examples. In the first example AS is used. In the second example, it is not. Again, your formatting standards should specify whether the AS keyword is included.

Commas

One of the quickest ways to wreak havoc among T-SQL developers is to start a discussion about how commas should be treated within T-SQL code, particularly in a SELECT list. Even so, a standard should be set, and to do so, you should take into account several factors:

  • Should commas be treated differently in different circumstances? For example, should columns in a SELECT list be treated the same as columns in an ORDER BY clause? What about the commas used in a list of parameters?
  • For object names that are separated into multiple lines, as is sometimes the case for a SELECT list, should commas end the line or begin the line?
  • Should spaces or tabs ever be used before or after the commas?

The questions are pretty straightforward; an agreed-upon solution is not. Take a look online and you’ll see endless comments dedicated to this issue. Before you do that, however, let’s look at a few examples of how commas can be treated. The following SELECT statement includes two series that require commas—the SELECT list and the ORDER BY clause:

SELECT FirstName,

   MiddleName,

   LastName,

   City,

   StateProvinceName

FROM HumanResources.vEmployee

WHERE JobTitle LIKE ‘Production Technician%’

ORDER BY StateProvinceName, City

Notice that in the SELECT list the commas are placed at the end of the column names. However, in the ORDER BY clause, the column names are on one line, so the comma comes after the first column name, followed by a space. Another approach you can take is to precede the column names in the SELECT list with a comma, as in the following example:

SELECT FirstName

   ,MiddleName

   ,LastName

   ,City

   ,StateProvinceName

FROM HumanResources.vEmployee

WHERE JobTitle LIKE ‘Production Technician%’

ORDER BY StateProvinceName, City

In this case, the comma is placed directly in front of the column names in the SELECT list. However, you can also choose to add a fixed number of spaces after each column:

SELECT FirstName

,   MiddleName

,   LastName

,   City

,   StateProvinceName

FROM HumanResources.vEmployee

WHERE JobTitle LIKE ‘Production Technician%’

ORDER BY StateProvinceName, City

Now let’s take a look at an example in which the ORDER BY clause is treated like the SELECT list:

SELECT FirstName,

   MiddleName,

   LastName,

   City,

   StateProvinceName

FROM HumanResources.vEmployee

WHERE JobTitle LIKE ‘Production Technician%’

ORDER BY StateProvinceName,

   City,
   LastName

As you can see, there are several approaches you can take with commas. And comma use is by no means limited to SELECT lists and ORDER BY clauses. In the following DDL statements, commas are used to separate the elements of the OBJECT_ID function and the column definitions:

IF OBJECT_ID

   (

      ‘ProductDocs’,

      ‘U’

   ) IS NOT NULL

DROP TABLE ProductDocs

GO

CREATE TABLE ProductDocs

(

  DocID int NOT NULL IDENTITY,

  DocTitle nvarchar(50) NOT NULL,

  DocFileName nvarchar(400) NOT NULL,

  CONSTRAINT PK_ProductDocs_DocID PRIMARY KEY CLUSTERED (DocID ASC)

)

GO

In this case, the function parameters are treated like the column definitions. Undoubtedly, you’ll come up with your own strategies for how to handle such issues as functions and columns. However, whatever strategy you implement, it must take into account the various ways that commas are used. And part of those considerations will depend on how you space and align the various elements in your statements.

Spacing and Aligning

Everyone has an opinion about how his or her code should be spaced, indented, and broken across lines. There are as many ways to lay out your code as there are people developing that code. In fact, trying to determine the spacing and alignment of the various T-SQL elements might prove to be one the more challenging tasks in your standards process, but the more consistent the code across your organization, the better. For that reason, you should take into account a number of factors when planning your code’s layout:

  • What will the policy be for new lines (linefeeds)? For example, should there be a new line for each clause? Should there be a new line for each clause keyword and a separate line for the arguments to that keyword? For instance, should the FROM clause be on one line and the table name be on the next line?
  • What is the maximum number of characters permitted in each line? Should line widths provide for printing the code without adding unplanned line breaks?
  • How will you handle clauses that exceed the maximum line width? Should subsequent lines be indented?
  • What is the general policy for indentation? For example, in a SELECT statement, should each clause after the SELECT clause be indented? Should arguments to the clause be indented more?
  • Will you use spaces or tabs for indentation? If you use spaces, how many spaces per indent?
  • How will you handle joins in your queries? Will the JOIN and ON keywords start new lines? Should each clause in a join be on separate lines?
  • How should XML-related queries be handled? For example, how should you format a query that includes an XML method in the SELECT list? What if the method references a namespace?

Now let’s look at a few examples that demonstrate different spacing strategies. In the first example, each clause begins on a separate line:

SELECT FirstName, MiddleName, LastName, City, StateProvinceName

FROM HumanResources.vEmployee

WHERE JobTitle LIKE 'Production Technician%'

ORDER BY StateProvinceName, City

Compare this example with the next one, in each clause and each set of clause arguments begin on separate lines:

SELECT

   FirstName, MiddleName, LastName, City, StateProvinceName

FROM

   HumanResources.vEmployee

WHERE

   JobTitle LIKE 'Production Technician%'

ORDER BY

   StateProvinceName, City

In both cases, the code can be easily read because these are very simple statements. However, the more complex your statements, the more important it is to have formatting standards that can deal with these complexities. For instance, if your clauses don’t fit into a single line, you must determine how you will handle line wraps, such as the SELECT list in the following example:

SELECT FirstName, MiddleName, LastName,

   City, StateProvinceName

FROM HumanResources.vEmployee

WHERE JobTitle LIKE 'Production Technician%'

ORDER BY StateProvinceName, City

Notice that the SELECT list now spans two lines and that the second line is indented. However, instead of taking this approach you might separate the elements in the SELECT list and ORDER BY clause onto separate lines:

SELECT

   FirstName,

   MiddleName,

   LastName,

   City,

   StateProvinceName

FROM

   HumanResources.vEmployee

WHERE

   JobTitle LIKE 'Production Technician%'

ORDER BY

   StateProvinceName,

   City

Notice also that the elements that make up each clause are indented three spaces to clearly delineate each clause and their elements. In fact, there are numerous indenting strategies you can implement. For example, in the next SELECT statement, each clause after the SELECT clause is indented:

SELECT FirstName, MiddleName, LastName, City, StateProvinceName

   FROM HumanResources.vEmployee

   WHERE JobTitle LIKE 'Production Technician%'

   ORDER BY StateProvinceName, City

Another approach you can take is to indent the elements so they all start at the same margin, as in the following example:

SELECT   FirstName,

         MiddleName,

         LastName,

         Cityty,

         StateProvinceName

FROM     HumanResources.vEmployee

WHERE    JobTitle LIKE 'Production Technician%'

ORDER BY StateProvinceName, City

            As you can see, all the columns and table names line up. Also, in this case, tabs are used instead of spaces to indent the elements. The use of tabs instead of spaces can initially be easier, but when you start moving code around and cutting and pasting, spaces seem more effective. But then again, this is a judgment call, one that you have to make yourself. In the meantime, take a look at the following example, which includes a join in the FROM clause:

SELECT cnt.FirstName, cnt.LastName,

   emp.LoginID, emp.Title

FROM HumanResources.Employee emp

JOIN Person.Contact cnt

   ON emp.ContactID = cnt.ContactID

ORDER BY cnt.LastName

            In this example, the JOIN keyword starts a new line, following by the joined table. The ON clause follows on another new line and is indented. However, you might take a different strategy when working with joins, such as that in the following statement:

SELECT cnt.FirstName, cnt.LastName,

   emp.LoginID, emp.Title

FROM HumanResources.Employee emp JOIN

   Person.Contact cnt ON

   emp.ContactID = cnt.ContactID

ORDER BY cnt.LastName

This time the JOIN and ON keywords are added before the line break. Another strategy you might employ is to indent the entire join condition, as in the following example:

SELECT

   cnt.FirstName,

   cnt.LastName,

   emp.LoginID,

   emp.Title

FROM

   HumanResources.Employee emp

   JOIN Person.Contact cnt

   ON emp.ContactID = cnt.ContactID

ORDER BY

   cnt.LastName

When setting up your formatting standards, you should also take into account XML-related queries. For instance, the following select statement uses the XML query() method to retrieve the job candidate’s name:

SELECT JobCandidateID, EmployeeID, Resume.query(

   'declare namespace ns=

      "http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/Resume";

   data(/ns:Resume/ns:Name/ns:Name.Last)') AS CandidateName

FROM HumanResources.JobCandidate

WHERE EmployeeID IS NOT NULL

Notice how the method’s argument is set off from the rest of the SELECT list. Also notice that the namespace wraps to a second line. Another approach you can take is to isolate the method’s argument even further:

SELECT JobCandidateID, EmployeeID,

   Resume.query

   (

      ‘declare namespace ns=

      “http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/Resume”;

      data(/ns:Resume/ns:Name/ns:Name.Last)’

   ) AS CandidateName

FROM HumanResources.JobCandidate

WHERE EmployeeID IS NOT NULL

XML can be tricky when trying to implement formatting standards because the XQuery elements can become quite long, particularly when the namespace is being referenced, as in the examples above.

Code Blocks

For this article, I use the term code block loosely. In this case, it refers to any sort of block of code, whether it’s a TRY/CATCH construction, column definitions enclosed in parentheses, a complex Boolean expression, a subquery, or any other grouping of code. And the way you lay out code blocks is tied to the decisions you make about spacing and alignment. When determining how to format blocks of code, you should take into account the following considerations:

  • How should you handle code blocks such as BEGIN/END, IF/ELSE, or TRY/CATCH? Should you specify policies for each type of code block? How will you handle the elements in each block? Should inside elements be indented? Should the keywords themselves be in separate lines?
  • How will you handle code blocks when one is imbedded in another? For example, if you use BEGIN/END blocks within your IF/ELSE construction, how should each element be treated? Should you indent the BEGIN/END blocks? Should keywords such as ELSE and BEGIN be placed on separate lines?
  • How should subqueries be handled in your T-SQL code? Should they be treated the same regardless of where they occur? For example, should a subquery in a SELECT list be treated differently from a subquery in a WHERE clause? What about indentation? Should subqueries be on lines separate from other elements?
  • How should expressions be formatted in your T-SQL statements? Should they be separated from other elements in the statement? Should conditional operators be on separate lines?
  • How will you treat parentheses and braces in your statements? Should line breaks and indentation be used to set them off from other statement elements? Should their format be based on how they’re used? After all, parentheses are used for expressions, data definition language (DDL) statement, function parameters, and subqueries. Should they be treated differently in each case?

Let’s look at some code they help to illustrate these issues. In the following CREATE TABLE statement, the set of parentheses that encloses the column definition are set apart from the rest of the statement:

IF OBJECT_ID(‘ProductDocs’, ‘U’) IS NOT NULL

DROP TABLE ProductDocs

GO

CREATE TABLE ProductDocs

(

   DocID int NOT NULL IDENTITY,

   DocTitle nvarchar(50) NOT NULL,

   DocFileName nvarchar(400) NOT NULL,

   CONSTRAINT PK_ProductDocs_DocID PRIMARY KEY CLUSTERED (DocID ASC)

)

GO

As you can see, the opening parenthesis is on a separate line, the closing parenthesis is on its own line, and everything in between is indented. However, parentheses and the elements they enclose can be treated in a variety of way. For example, the following CREATE TABLE statement, the new line comes after opening parenthesis and after the closing parentheses:

IF OBJECT_ID(‘ProductDocs’, ‘U’) IS NOT NULL

DROP TABLE ProductDocs

GO

CREATE TABLE ProductDocs (

   DocID int NOT NULL IDENTITY,

   DocTitle nvarchar(50) NOT NULL,

   DocFileName nvarchar(400) NOT NULL,

   CONSTRAINT PK_ProductDocs_DocID PRIMARY KEY CLUSTERED (DocID ASC))

GO

Another issue is how to handle code blocks such as IF/ELSE. In the following example, each keyword that starts or ends a block is on its own line:

DECLARE @a varchar(10)

DECLARE @b varchar(10)

SET @a = ‘one’

SET @b = ‘two’

IF ((@a = @b) OR (@a = ‘two’))

BEGIN

   PRINT ‘The first condition is correct.’

END

ELSE

BEGIN

   PRINT ‘The first condition is incorrect.’

END

In this case, only the contents of the BEGIN/END blocks are indented. However, because the BEGIN/END blocks are embedded in the IF/ELSE blocks, you might decide to indent to the BEGIN/END keywords as well, as shown in the following example:

DECLARE @c varchar(10), @d varchar(10)

SET @c = ‘one’

SET @d = ‘two’

IF (@c = @d) OR (@c = ‘two’)

   BEGIN

      PRINT ‘The first condition is correct.’

   END

ELSE

   BEGIN

      PRINT ‘The first condition is incorrect.’

END

Another consideration is how to handle expressions, such as the Boolean expression after the IF keyword. In the previous example, the expression is on the same line as the IF keyword. However, you can separate the expression elements as well, as shown in the following example:

DECLARE @e varchar(10), @f varchar(10)

SET @e = ‘one’

SET @f = ‘two’

IF (

      (@e = @f)

      OR

      (@e = ‘two’)

   ) BEGIN

   PRINT ‘The first condition is correct.’

END

ELSE BEGIN

   PRINT ‘The first condition is incorrect.’

END

Notice also that first BEGIN comes at the end of the Boolean expression and the second BEGIN is on the same line as ELSE. Again, you must decide how you want to handle each of these elements when defining your standards. Now let’s look at an example SELECT statement that includes a subquery:

SELECT cnt.FirstName, cnt.LastName, emp.SickLeaveHours,

   (SELECT AVG(SickLeaveHours)

      FROM HumanResources.Employee) AS AvgSickLeave

FROM HumanResources.Employee emp

   JOIN Person.Contact cnt

   ON emp.ContactID = cnt.ContactID

WHERE emp.EmployeeID = 1

As you can see, the subquery is an element in the SELECT list and is long enough to require two lines. You can also choose to separate out the subquery even more:

SELECT cnt.FirstName, cnt.LastName, emp.SickLeaveHours,

   (

      SELECT AVG(SickLeaveHours)

      FROM HumanResources.Employee

   ) AS AvgSickLeave

FROM HumanResources.Employee emp

   JOIN Person.Contact cnt

   ON emp.ContactID = cnt.ContactID

WHERE emp.EmployeeID = 1

Again, all these details are the types of considerations you should take into account so that you can have consistent code across your organization.

Comments

Comments are fairly self-explanatory. If you plan to use them, then you should have policies that take into account their usage, in which case you should consider the following:

  • Should comments always be included in code files and T-SQL statement?
  • If opening comments in a code file are used, should they be standardized? For example, should they always be in the same format and include the same information, such as the developer’s name, revision history, and purpose of the code?
  • Should you use only one type of comment on your code? For example, should you use the slash/asterisk (/*…*/) convention, rather than the double-dash (--) convention?

The following example shows both types of comments supported by T-SQL and how comments can be used before or after the code, or within the code:

/*

Retrieves employee data for Production Technicians

Orders data by state, then city

*/

SELECT FirstName, MiddleName, LastName, --retrieve full name

   City, StateProvinceName

FROM HumanResources.vEmployee

-- Pull Production Technicians only

WHERE JobTitle LIKE 'Production Technician%'

ORDER BY StateProvinceName, City --order by state, then city

/*

CONFIDENTIAL

*/

Naming Conventions

Determining naming conventions is not really a formatting issue, per se, but you’ll seldom get into discussions about formatting without eventually talking about how to name things, so I thought I would raise this issue so it’s on your radar as you set up your standards. That said, here are a few considerations to take into account:

  • Should you use different naming standards for different object types? For example, should you differentiate between tables, columns, stored procedures, functions, views, constraints, indexes, and so on?
  • If you implement naming standards based on the object type, what will the standards be? For example, should all stored procedure names be based on an action? Should primary key constraints be based on column names?
  • Should you standardize names for different types or groupings of objects within a database? For instance, should all tables related to marketing be prefixed with “Mkt”? Should all column names that specify an identification integer value end in “ID”? Should many-to-many bridge tables reflect the names of the tables they are bridging?
  • Should table and view names be singular or plural, such as BookTitle versus BookTitles? What about nouns that have a plural form, such as people versus person?
  • Should object names be prefixed or suffixed? Should the use of  prefixes or suffixes be based on the object type? For example, would you use “usp_” to prefix the names of user-defined stored procedures, or “pk_” to prefix the names of primary key constraints? Should some object types be prefixed but not others?
  • Can underscores (_) or other special characters be used in object names? What about keywords? Spaces? Should there be a policy that no name be used that cannot be called without enclosing that name in brackets?
  • Should abbreviations be used for object names? How about single letters?

Moving Forward

In addition to the number of issues I’ve raised above, you should also determine whether to develop a set of standards for each type of statement. For example, do DDL and DML statements require different rules. Your standards might also want to cover how statements are placed within a code file. For instance, should all variable assignments (DECLARE and SET) in a stored procedure be at the beginning of the procedure definition?

There will, of course, be other issues that you’ll want to address when putting together your formatting standards. But the questions above should, at least, provide you with a starting point. They should also demonstrate the breadth of this undertaking as you try to negotiate the many details that will need to be decided upon in order to implement a set of policies that define how your organization’s T-SQL code should be formatted.

Keep in mind, however, that even with the best effort, you’ll find that defining standards is an ongoing process. You should try to lock down and implement your styles as soon as possible, but know  you’ll inevitably run into situations when those standards don’t cover what you need or will have to be modified to meet changing requirements. For that reason, along with the standards, you should also put in place a process that allows you to implement changes as quickly and as smoothly as possible. And you should try to keep your standards documents as current as possible. In the meantime, this article should give you a sense of the types of issues you’ll need to tackle and the number of decisions you’ll have to make to implement a comprehensive and effective formatting strategy.



This article has been viewed 23259 times.
Robert Sheldon

Author profile: Robert Sheldon

After being dropped 35 feet from a helicopter and spending the next year recovering, Robert Sheldon left the Colorado Rockies and emergency rescue work to pursue safer and less painful interests—thus his entry into the world of technology. He is now a technical consultant and the author of numerous books, articles, and training material related to Microsoft Windows, various relational database management systems, and business intelligence design and implementation. He has also written news stories, feature articles, restaurant reviews, legal summaries, and the novel 'Dancing the River Lightly'. You can find more information at http://www.rhsheldon.com.

Search for other articles by Robert Sheldon

Rate this article:   Avg rating: from a total of 111 votes.


Poor

OK

Good

Great

Must read
 
Have Your Say
Do you have an opinion on this article? Then add your comment below:
You must be logged in to post to this forum

Click here to log in.


Subject: JOIN Statements
Posted by: Peter (not signed in)
Posted on: Thursday, August 27, 2009 at 12:50 PM
Message: Only example out of the list above that drives me nuts is putting the JOIN at the end of the prior line. Sure it's great to see that all of my tables line up, but then I need to look at the prior line to figure out how. :P The rest seems more a matter of preference than anything else. I've run into that particular coding semi-standard here several times (not used consistently) and it just makes it hard to read to me.

I appreciate the rather thorough look at SQL Coding standards. This was a lot more detailed than I was expecting and is worth pondering a little if you're just starting a new DB Project.

Subject: Code Formatting
Posted by: Paul Hunter (view profile)
Posted on: Thursday, August 27, 2009 at 9:25 PM
Message: I have a feeling I'd have some different choices on the formatting but, you pose a rational framework that I could follow. Thanks for the article.

Subject: I loved your tolerant approach!
Posted by: Alex_Kuznetsov (view profile)
Posted on: Friday, August 28, 2009 at 8:54 AM
Message: The following sounds great: "There’s no real right or wrong, as long as the standards are applied consistently".

In my opinion it is very important that the whole query fits on a screen. If you ever work on a laptop, this means just one very small screen, so long lines are not desirable. Also if the query is long and complex, we should list several columns on one line, avoid ORDER BY on its own line and such. What do you think?

Subject: Ongoing process
Posted by: gserdijn (not signed in)
Posted on: Saturday, August 29, 2009 at 9:20 AM
Message: "You’ll find that defining standards is an ongoing process". Well put.

In select statements I use lowercase for the columns and tables, uppercase for the keywords and camelcase only for derived tables, functions and variables. Joins on one line, do not use aliases unless functional.

The more complex the query is, the more whitespace I tend to use (and comments of course).

Since we started using SQL Server 2008 we are addding the semicolon (;) to the code.

Subject: I wrote a whole book on this!
Posted by: Joe Celko (not signed in)
Posted on: Thursday, September 03, 2009 at 11:25 AM
Message: I wrote a whole book on this topic; SQL PROGRAMMING STYLE. I did research on formatting code while working for the US Army in the early days of "the Structured Programming Revolution". It is not a matter of taste in many cases, but it is measurable.

A lot of stuff was lying around in typography studies and conventions, but they had not been applied to IT yet. Eye movement, Boumas, use of rivers, etc. are all part of the literature. The best work was done for newspaper copy then picked up by book publishers.

We found that good formatting saved 8-12% of the time to maintain code. The classic experiment was to insert (n) bugs in code, then see how long it took an experienced programmer to find them. Later people tracked eye movements.

Today, we have the ISO-11179 standards for naming data elements, too.


Subject: indenting the JOINs
Posted by: Adam Machanic (view profile)
Posted on: Monday, September 07, 2009 at 9:13 PM
Message: I don't like the JOINs to be indented. In my opinion they're logically equivalent with the FROM. I also put the ON on the same line as the JOIN, because it applies to the ENTIRE join, not just the first predicate:

SELECT
...
FROM T1
INNER JOIN T2 ON
T1.A = T2.A
AND T1.B = T2.B


Subject: It's Great
Posted by: Kuldeep Mathur (not signed in)
Posted on: Monday, September 07, 2009 at 11:35 PM
Message: This is a great article 4 learner.Thanx alot to the author 4 this gr8 help.

Subject: Automatic SQL Formatter
Posted by: GuidoMarcel (not signed in)
Posted on: Tuesday, September 08, 2009 at 12:27 AM
Message: Hi, here is an automatic SQL Frmatter at http://www.sqlinform.com

Subject: standards schmambards...
Posted by: Anonymous (not signed in)
Posted on: Tuesday, September 08, 2009 at 1:54 AM
Message: if yr smart enough to write code u shld be smart enough to read code. regardless of standardization.

Subject: Thanks
Posted by: Anonymous (not signed in)
Posted on: Tuesday, September 08, 2009 at 2:00 AM
Message: thanks for nice article

Subject: Standards is the key
Posted by: Artem (not signed in)
Posted on: Tuesday, September 08, 2009 at 2:13 AM
Message: Thanks for well thought through article. I am coding t-sql by using code conventions very close to what have been describing here. I would say the main key of any code conventions is that whole team follow it. It is of course good of code looks more readable, but it should look consistent across the whole source code.

Peter, I agree with you - JOIN at the end of prev row does not make sense to me. I'd follow second snippet with JOIN on the new line

Just my two cents :)

Subject: RE: standards schmambards...
Posted by: Gary Varga (view profile)
Posted on: Tuesday, September 08, 2009 at 2:46 AM
Message: Dear (the obviously brave and non-antagonising) Anonymous,

I think that the author and his audience are indeed smart enough to read code in any form, however, are you smart enough to want to make that task even easier?

It is important to understand that formatting usually has no effect on the performance of the code but it does have an effect on the productivity of the maintainer of the code (see Joe Celko's post for a more succinct summary).

Yours hopefully,
Gaz

Subject: Re: capitalisation
Posted by: Laurence (not signed in)
Posted on: Tuesday, September 08, 2009 at 4:04 AM
Message: My 2 cents about capitalisation:

I use all lowercase for all SQL reserved words, types, keywords etc. I adopted this recently after years of using uppercase, for 2 reasons:

1. I find it a more natural, pleasant experience to read lowercase text. In most other mediums (literature, newsprint etc) text is lowercase. All uppercase text to me at least occurs as heavy and emphatic (like the maxim for email text: uppercase = shouting).

2. Its easier to type. Constantly switching between upper and lowercase is tiring. I finally stopped the practise when I noticed that after years of doing this myself, the last joint of my left finger had developed a slight inward kink from leaning on the shift key!

I use camel case for all object names (tables, column names etc). This is because these names frequently compound several words into a single string and camel case makes this readable.

Subject: brilliant
Posted by: sean (view profile)
Posted on: Tuesday, September 08, 2009 at 4:49 AM
Message: thankyou for this article, it has cured my insomnia. keep the good work up

Subject: My standard
Posted by: Jarmo (not signed in)
Posted on: Tuesday, September 08, 2009 at 5:14 AM
Message: Perhaps not the optimal standard, but I use this standard because I enjoy it's readability(tab separated):

SELECT
cnt.FirstName
, cnt.LastName
, FullName = cnt.FirstName + ' ' + cnt.LastName
, emp.LoginID
, emp.Title
FROM
Employee emp
INNER JOIN Contact cnt ON emp.ColumnA = cnt.ColumnA
AND emp.ColumnB = cnt.ColumnB
WHERE
emp.LogId > 0
AND cnt.Title like '%great%'
ORDER BY
cnt.LastName
, emp.Title

Subject: ... about camel case
Posted by: Hercules Gunter (view profile)
Posted on: Tuesday, September 08, 2009 at 6:54 AM
Message: What you offer is not camel case, but Pascal case. The distinction is that camel case starts with a lowercase letter, and is much used in languages based on C for function names. Pascal case starts with an uppercase letter, and presumably began with the Pascal language. A small distinction, I know.

Subject: Coding Styles
Posted by: Dennis O'Connor (not signed in)
Posted on: Tuesday, September 08, 2009 at 7:56 AM
Message: Another situation you could add to your list is where to put ANDs and ORs. Some put them at the end of a line, others put at the beginning. Sort of like your comma examples.

Subject: Indenting on a join
Posted by: JohnLeo Carton (not signed in)
Posted on: Tuesday, September 08, 2009 at 8:06 AM
Message: Generally i find that if you wish to continue any line to a new line you should ensure the first word is indented and clearly marks the line as a continuation
e.g
Select
Cast a.Field3 when 1 then a.Field2 * a.Field3
else a.Field3 end as Compute1
instead of
Select
Case a.Field3 when 1 then
a.Field2 * a.Field2 else a.Field3 end as
Compute1

In the above example the word "else" obviously denotes a continuation whereas "a.Field2" may at first glance be another field

This extends to joins specifically when joining many fields
e.g
Select
...
From table1 a
inner join table2 b
on a.Fld1 = b.Fld1
and a.Fld2 = b.Fld2
and a.Fld3 = b.Fld3

instead of

Select
...
From table1 a inner join table2 b on
a.Fld1 = b.Fld1 and a.Fld2 = b.Fld2 and
a.Fld3 = b.Fld3


Mind you most of my co-workers think i am a bit excessive on the indents.

Subject: you say, I say
Posted by: Anonymous (not signed in)
Posted on: Tuesday, September 08, 2009 at 9:02 AM
Message: tomato - tomato

Subject: column names
Posted by: Mark LaBree (not signed in)
Posted on: Tuesday, September 08, 2009 at 9:22 AM
Message: Another option that is useful when developing information using Case, Cast and Convert statemtnts and the like is leading a line with the name of the column --
instead of
Cast(Field as Nummeric(12,2)) as Name
try
Name = Cast(Field as Nummeric(12,2))

This helps when you have to make many adjustments in complex Case statements or Convert and Cast statements, you do not have to remember to add the "as Name" each time the code is changed.

Subject: Coding Style
Posted by: Anonymous (not signed in)
Posted on: Tuesday, September 08, 2009 at 9:44 AM
Message: Great article. Its easier to use key words in uppercase and column names in lowercase.As for the join though it may be contentious,it should always be on a new line for readibility purposes.

Subject: Take another look at RedGate SQL Refactor
Posted by: Anonymous (not signed in)
Posted on: Tuesday, September 08, 2009 at 9:44 AM
Message: Great article and interesting comments. In addition to RedGate's SQLPrompt, their SQL Refactor product allows for fine control over formatting and can be applied to existing code with a single key-stroke. It's worth every penny of the $295 price, especially when you consider you can define a template of settings and save and share it amongst a group of developers.

Subject: case and space
Posted by: Robert Carnegie (not signed in)
Posted on: Tuesday, September 08, 2009 at 9:55 AM
Message: When Microsoft SQL Server generates code, keywords are usually CAPITAL. I go with that; not for casual queries, but I often revisit work and CAP the keywords. The comment about an online SQL formatter is interesting, although maybe sending copies of all of our Transact-SQL programs to a complete stranger's server isn't going to be best practice.

Otherwise I go for readability and editability, taking it that horizontal indentation, inter-character spacing, and full name qualification are cheap, and vertical spacing is free. I also use brackets a lot. So IF ( x = 1 ) BEGIN SET y = y + 5 END has new lines before BEGIN, SET (with 4 spaces indent) and END. Other styles or other languages want to indent BEGIN/END, but that's cheap, not free, so I don't.

Table aliases aren't distinguished between user, system, temporary or variable, basically so I can re-use the same code with a different table type and the same alias terms, and also because I didn't think of it. At least one program constructs dynamic SQL that uses a global (careful!) temporary or user table with the same data, depending on a flag. Aliases also reflect the abstract role of a table in a join, not necessarily table name, so that a rewrite to a different actual table isn't jarring.

Lately I started using multi-line variable declare, types lined up, with comma a space before the variable name instead of after. Likewise table column lists, with also newline six spaces newline every fourth column name -that pays off if they're long and you have to find why you're INSERT INTO table (123 column names) SELECT (124 columns), which one is missing or extra.

OR clauses, sometimes GROUP BY, I do comma and column name or expression indented and on SEPARATE lines, which makes it easier to grab one or more and move them up or down in the list, and is another motive for my comma policy in other areas.

But still in this office, we can usually tell which of us wrote the code...

Subject: begin end colon
Posted by: Robert Carnegie rja.carnegie@excite.com (not signed in)
Posted on: Tuesday, September 08, 2009 at 10:05 AM
Message: Oh, and BEGIN / END is a presentation choice where the language doesn't require it. How often have you written IF condition STATEMENT1 and then changed it to IF condition STATEMENT1 STATEMENT2 which doesn't do what you expected? Well, if you always write IF condition BEGIN, you don't.

Also,

STATEMENT1
;
STATEMENT2
;

means that a syntax error actually in STATEMENT1 isn't going to be misidentified by the server as "no longer makes sense" somewhere inside STATEMENT2 - or not identified at all and doing something you don't want to think about.

I think this stuff looks pretty, too. Until you start reading it.

I can maybe retire my ugly error catcher for SQL Server 2000, since we just went up to 2005:

SET @returnerror = @@ERROR IF ( @returnerror <> 0 ) GOTO failure
...
GOTO terminate
failure:
(cleanup stuff)
temrminate:

Subject: order by
Posted by: Robert Carnegie (not signed in)
Posted on: Tuesday, September 08, 2009 at 10:07 AM
Message: Ps, I mean

ORDER BY
column1
,
column2
,
column3

Subject: Coincidence
Posted by: Anonymous (not signed in)
Posted on: Tuesday, September 08, 2009 at 11:03 AM
Message: Is it my imagination or well-known fact that all good DBAs are bald?

Subject: Qualification
Posted by: Anonymous (not signed in)
Posted on: Tuesday, September 08, 2009 at 11:14 AM
Message: I would say it is important to schema qualify all object references - because it has an impact on execution speed. And it's important not to database qualify object references because you might actually want the same procedure in a test database one day... (!)

Subject: Tools
Posted by: Anonymous (not signed in)
Posted on: Tuesday, September 08, 2009 at 12:05 PM
Message: Agree to a template for all header comments and get everyone to comply. For everything else find an automated formatting tool, find what it can do, get everyone to agree to what they can live with and then distribute to your team the file used by the program to determine formatting. Whenever you find code that doesn't follow the standard, format it with the standard template. As an alternative let everyone have their own standard and reformat what you are working on to your standard using the automated tool.

Subject: Tools & Formatting in general
Posted by: Anonymous (not signed in)
Posted on: Tuesday, September 08, 2009 at 2:16 PM
Message: I love these wars over formatting and was surprised how many entries there were before someone who made sense.
There are plenty of editors out there that can "pretty print" SQL or any other language to any arbitrary formatting rules set.
If you don't like the look for production, make if part of your change control to format to SQL text.
Agreed again on having a header for change control, code purpose and design comments. If code is missing comments, then reject the change control. It's your only shot at control.

Subject: Thanks!
Posted by: Johnathon Wilde (not signed in)
Posted on: Tuesday, September 08, 2009 at 2:23 PM
Message: Robert, thanks for a the very well thought out and written article! I'm particularly impressed with how you managed to keep your personal opinions out of the article and instead focused on the fundamental questions at hand. Extremely well written...thanks!

jstw

Subject: And finally here it is....
Posted by: Paul Jilek (not signed in)
Posted on: Tuesday, September 08, 2009 at 4:53 PM
Message: Robert, Fantastic job in capturing all the different flavours of formatting. I have standard here at work which I religiously follow. I have try to impart this to my manager who's old school (unix) and would prefer not to bother with the detail. He is a slave to the generated code from SMS: when developing views creates a complete mess. Can you get into Microsoft's ear and get them to improve the SMS generator? I'm sick of cleaning up my manager's code to make it legible.

Paul

Subject: Shortcuts
Posted by: parody (view profile)
Posted on: Wednesday, September 09, 2009 at 4:24 AM
Message: I like that there are so many variations, it allows us to add a bit of our own "creativity" into the code! But agree consistency is the key no matter how you write it - at the very least within one piece of code. With large departments employing people from varied backgrounds it would be near impossible to enforce a standard upon them all (without the help of 3rd part formatting software) especially with the high staff turnover generally within the IT profession. Habits are hard to break. I am however quite anal about my formatting and frequently cringe when I see poorly formatted code.

This is probably quite general knowledge but just in case it helps someone, query analyzer and management studio offer shortcuts to change text in the editor to be upper or lower case (amoung other handy things like commenting or identing blocks of highlighted code). For example crtl-shift-u for upper case and ctrl-shift-l for lower. I use them quite often. Take a look here for a complete list http://msdn.microsoft.com/en-us/library/ms174205.aspx

Note that in management studio you must change your keyboard environment setting to use the 2000 scheme for some to work (like ctrl-shift-l doesnt work in standard mode).

Subject: Commas
Posted by: Nick (view profile)
Posted on: Wednesday, September 09, 2009 at 10:12 AM
Message: Nice article.

Comma placement can depend on the use to which the SQL will be put. I find commas after the fields much more readable for 'production' code, but a lot of my time is spent writing 'exploratory' queries on the data.

In this case I put commas first on a line before the fields. Why? - because a lot of my time is spent finessing the query which may involve adding/removing fields. With commas at the front all you need is to add '--' at the start of that line to remove a field without affecting any other line, rather than commenting out the trailing comma in the line above.

Subject: Avoiding the humps
Posted by: Charles Kincaid (view profile)
Posted on: Wednesday, September 09, 2009 at 11:04 AM
Message: One noted pundit wrote, “Even Microsoft has given up on camel case.” I’ve taken to putting all the reserved words in upper case and everything else in lower case. Then I’ve also changed the fonts on my editors as well.

The comma a the beginning of the column name on a line helps in that it is often easier to rearrange things during development. Since the extra spaces and line breaks don’t have that much impact I leave them. It helps the readability of the next poor sole working on that code. (usually that poor slob is me and I need all the help I can get.)

ORDER BY 3, 2, 1 Excuse me? Who thought that THIS way a great idea? Why not SELECT 5, 6, 7, 8 FROM all_that_jazz? Just rely on column order like the asterisk. (you spotted the humor?)

Speaking of stars. I noted that
SELECT COUNT(1) FROM X
produces the same results as
SELECT COUNT(*) FROM X
in SQL Server so the asterisk is now a banned character.

Subject: Nice Article...
Posted by: Steve (view profile)
Posted on: Wednesday, September 09, 2009 at 11:16 AM
Message: but I have to take exception to

"The following example uses more meaningful abbreviations for the table aliases:" (stating that emp and cnt are more "meaningful" than e and c for table abbreviations for "Employee" and "Contact" respectively.)

The single letter names have more meaning for me. I tend to hear the code as I read it, and although "emp" is okay, "cnt" is actually distracting, due to its closeness to a term which would likely be caught by your language filter...

Oh, and RE: Coincidence, that's not the standard male pattern baldness you're seeing. It's DBA Pattern Baldness (DPB), which is caused by having to fix badly formatted SQL code written by developers who refuse to adhere to standards...

Subject: formatting
Posted by: Anonymous (not signed in)
Posted on: Wednesday, September 09, 2009 at 12:48 PM
Message: I've gotten past worrying about how other developers format by using Redgate's SQL Refactor to format SQL. You specify your preferences (once) of how you want your formatting to appear and then press a button, no problem.

Thus, the first thing I do when I have to modify someone else's procedure is to re-format it to my liking, and they can do the same.

Subject: Awesome article!
Posted by: Will Strohl (not signed in)
Posted on: Wednesday, September 09, 2009 at 4:18 PM
Message: I loved your article. I am a stickler for readability in T-SQL. I pimped your article as well:

http://pimpthisblog.com/Transact-SQL-Formatting-Standards-Coding-Styles

Subject: Great outline for creating a T-SQL Standard
Posted by: YSLGuru (not signed in)
Posted on: Wednesday, September 09, 2009 at 5:45 PM
Message: Great piece on how best to generate a SQL Standard. While many have their preferences on HOW TO handle T-SQL code I think it's important to admit that what you like may not always be whats in the best interest of all in your department/company both current and future employees. When deciding on a standard you should follow a priority list that may not be what you'd follow if it were all up to you alone:

1) What standard will server my company/product best so that all wo create, edit and review T-SQL code will be able to most easily understand what is intended and find with the least amount of effort any mistakes be the logical errors or just syntax.

2) Within the context of #1 above, what can I adjust without conflicting with #1 that will allow me to do my job as quickly and accurately as possible.

3)DOCUMENT, NOTATE, COMMENT everything and then go back and copy all your comments into a seperate file with no T-SQL Code and have another developer read it. If they can tell from just your comments what the code should be doing then you've properly documented it. if not then go back and add the missing pieces of info.

No matter how good your style is, if no one else can understand what's going on, and this applies to more then just T-SQL, then it's worthless.

Subject: formatting
Posted by: Anonymous (not signed in)
Posted on: Wednesday, September 09, 2009 at 6:20 PM
Message: Redgate's SQL Refactor is great. Let each developer do what (s)he wants, then run the code through Refractor, and viola, it is formatted to the standard.

It would be nice if MS did formatting in SMS like the VS IDE does.

Subject: formatting
Posted by: Anonymous (not signed in)
Posted on: Wednesday, September 09, 2009 at 7:04 PM
Message: Redgate's SQL Refactor is great. Let each developer do what (s)he wants, then run the code through Refractor, and viola, it is formatted to the standard.

It would be nice if MS did formatting in SMS like the VS IDE does.

Subject: good
Posted by: Anonymous (not signed in)
Posted on: Thursday, September 10, 2009 at 7:40 AM
Message: good

Subject: ... about camel case
Posted by: Jonathan Steinberg (view profile)
Posted on: Thursday, September 10, 2009 at 12:25 PM
Message:
Hercules Gunter wrote

>What you offer is not camel case, but Pascal case.
....
>A small distinction, I know.
I concur with the observation.
I may say though, that it's not a small distinction. When discussing standards (of all things) ,it is important to be exact in your terminology. E.G: Incorrectly using the term "camel case" in an organization's standards document will defeat the entire purpose of creating the standard!

Subject: Schema
Posted by: Craig Beere (not signed in)
Posted on: Thursday, September 10, 2009 at 8:18 PM
Message: "For example, should you always include the schema name with a table even if the schema is dbo?"

Yes.
For schemabinding.
For more resilient code (no dependancy on default schema).
For correct procedure plan caching.

Subject: Formatting of JOINs
Posted by: Jani (not signed in)
Posted on: Friday, September 11, 2009 at 5:12 AM
Message: I don't like indented JOINs. It makes joined tables less important than FROM table. Even visually, FROM is written in blue and JOIN is grey, so it stands out. For me SELECT, FROM, *JOIN, WHERE, GROUP BY, HAVING, ORDER BY belong to the same level.
If JOIN has several fields, depending on readability, I put ON to the next indented line, then AND, OR all at the beginning of one level indent to JOIN. That way it's easy to comment out part of joined fields just as it's easy to comment out part of field definition if commas are used at the start of the row.

Subject: Company/Project Standards vs. Industry Standards
Posted by: Paulo.Morgado (view profile)
Posted on: Friday, September 11, 2009 at 8:55 PM
Message: Great arcticle, Robert.

I myself, being a C# developer, tend to apply the same conventions to my T-SQL code.

However, I'm more in favor of industry standards over company or project standards.

If project standards are used, I have to change my mindset when changing projects train another developer that comes to the project. Since outsourcing is a reality, companies have to train consultants in the company’s standards or someone on the company has to be trained on the vendor’s standards (not to mention consultants that go from company to company).

Industry standards, on the other hand, are to be understood by all which improves readability and maintainability of the code and also makes it easier to read code in articles and books.

I have to confess that I’m biased against people that don’t show the proper respect for industry coding standards. I wonder that if they miss on the easiest part, how will they perform on more complex issues. But that’s just me.

Subject: Get rid of upper case
Posted by: Dave F (view profile)
Posted on: Saturday, September 12, 2009 at 11:06 PM
Message: With automatic keyword highlights in most sql query systems, it is redundant to uppercase SELECT, FROM, WHERE, etc. The color of the text should be enough to distinguish syntax oddities and reduces use of caps keys. In old line systems where syntax highlighting was absent, upper case made sense, but now I'm not sure it serves any purpose.

However, there is a place for camelCase for naming objects where each UC character can demarcate domain specific words, such as HomeAddress, WorkAddress, etc. CamelCase can avoid all the ugly underscore characters as well, which take 2 keystrokes (if you count shift).

Indenting is of course a personal choice but there should be some indenting for code blocks and perhaps carried over consistently across an application.

As for aligning, it should be sensible enough so copy and paste for reuse is made easy. Here, fewer lines to copy will reduce errors and speed up troubleshooting. In any case, consistency in indenting is probably more relevant here than any particular style as the author noted.

Hard returns and new lines seem to proliferate in SQL. For example, there's no need to put case statements in multiple lines if the logic is simple one or two choices. Having in one line helps compare subsequent case statements, if any. Of course wide monitors these days give us more flexibility in layout by not limiting the length of each line to just half the screen width as shown in many of the examples above.

Subject: this article is
Posted by: Anonymous (not signed in)
Posted on: Tuesday, September 15, 2009 at 6:33 AM
Message: just rudimentary. What are u professional guys fussing about?

Subject: What Joe Said
Posted by: Bryant (view profile)
Posted on: Tuesday, September 15, 2009 at 8:31 AM
Message: This whole issue would pretty much go away if more people read Joe Celko's book _SQL Programming Style_. It lays out the best practices and they are all backed up by research. I have never had a developer argue with me over standards after reading that book and it doesn't take very long to read. WELL worth the 25 clams at Amazon but you can buy it anywhere you like (ISBN 0120887975). I recommend getting two copies so you can keep one while the other is loaned out.

Disclaimer: I don't know Joe Celko, am not related to Joe (that I know of) and have never even met the man.

Subject: My two cents worth - I hope the indentions are maintained
Posted by: Anonymous (not signed in)
Posted on: Tuesday, September 15, 2009 at 11:00 AM
Message: Great mix of standards - here is the general guidelines I follow:
1. Keywords are CAPITALIZED
2. Alieses are lowercased
3. Column Names are CamelCased
4. When needed always use the AS Keyword for distinction
5. Following commas rather than leading - reads more naturally
6. Try, if feasable, to keep the table list lined up
with the JOIN commands following, and ON conditions indented.
7. I like to line up the AND/OR conditions right justified to the WHERE
clause to give a little more visibility to the entire WHERE block.
8. Never be afraid to use parenthesis when needed for clarity

SELECT
cnt.FirstName,
cnt.LastName,
(cnt.FirstName + ' ' + cnt.LastName) AS FullName,
emp.LoginID,
emp.Title
FROM
Employee AS emp INNER JOIN
Contact AS cnt
ON (emp.ColumnA = cnt.ColumnA
AND emp.ColumnB = cnt.ColumnB)
WHERE emp.LogId > 0
AND cnt.Title like '%great%'
ORDER BY
cnt.LastName,
emp.Title

Subject: Good Read
Posted by: B Van Allen (not signed in)
Posted on: Tuesday, September 15, 2009 at 11:50 AM
Message: I have seen all this somewhere before :). Good outline of the various issues around code formatting. I would include that Microsoft publishes standards for code in some ways by the examples and conventions they use in the product documentation itself. Internally this is what you see most commonly at MS itself...although...it does vary there too depending on the era in which the code was written or the team doing the documenting.

Consider this example, from the BOL coding exampels for CONVERT:

-- Use CONVERT.
USE AdventureWorks;
GO
SELECT SUBSTRING(Name, 1, 30) AS ProductName, ListPrice
FROM Production.Product
WHERE CONVERT(int, ListPrice) LIKE '3%';
GO

Uses CAPPED keywords, lower case datatyping, Camel case on user defined objects, and a semicolon to terminate.

Hope this finds you well Bob.

Subject: Thought provoking
Posted by: Anonymous (not signed in)
Posted on: Tuesday, September 15, 2009 at 12:31 PM
Message: I found that making the keywords for the root statements and then the other keywords (sub-queries, etc.) in lower case helps in long statements. Not quite a standard, but allows for visual placeholder while editing.

Subject: DROP / CREATE - Objects
Posted by: Pans (not signed in)
Posted on: Wednesday, September 16, 2009 at 12:10 AM
Message: Very nice information. Thanks

1. Droping and Creating TABLE is NOT mandatory (or) good practice I think. What about the lost DATA/Constraints.

2. Droping and Creating PROCEDURES is NOT mandatory. In SQL Server 2000, We dont have Modified/altered date, So that we have to DROP/CREATE the PROCEDURES to track the last modified/created date. But in 2005/2008 we have Create_Date & Modify_Date columns as well. So the ALTER is enough.

Subject: Using Wildcards in a Select Statement
Posted by: Tony555 (view profile)
Posted on: Friday, October 02, 2009 at 2:42 PM
Message: I know this isn't exactly germane but since you mentioned the SELECT * wildcard I wanted to point out a script I wrote which allows real SELECT wildcards as well as a bunch of other bells and whistles such as right justification of result data and the ability to select all BUT a set of columns. Google "sp_wcProject" if interested.

Subject: You must know the "why" behind your styles
Posted by: Seven24 (view profile)
Posted on: Thursday, October 15, 2009 at 11:12 PM
Message: > This whole issue
> would pretty much go
> away if more people
> read Joe Celko's book
> _SQL Programming Style

Reading is the beginning of enlightenment; not the end. Joe's style ideas are from the 1970's/1980's and punch cards. Many of the reasons for the styles he presents are outdated; some are not.

As the Machiavellian said in the Matrix, "Without WHY you have no power." The most important thing to any coding style is *reason* behind the style. For example, I prefer comma's at the beginning of the line because too many times I miss putting it at the end especially if the line contains code that itself has a comma (e.g. a literal string). Further, I do indent my Joins because there is a huge difference between the From clause and the Where clause.

Another example is capitalization. It is an approach that made sense with monochrome monitors and monochrome editors but those days are long gone. There is no reason to capitalize keywords. Interestingly, his reasons against camelCase, being harder to reader, are exactly my arguments against all caps.

 










Phil Factor
Finding Stuff in SQL Server Database DDL
 You'd have thought that nothing would be easier than using SQL Server Management Studio (SSMS) for searching... Read more...



 View the blog
Implementing User-Defined Hierarchies in SQL Server Analysis Services
 To be able to drill into multidimensional cube data at several levels, you must implement all of the... Read more...

Using the Filtering API with the SQL Comparison SDK
 Red Gate's SQL Comparison SDK provides a means to compare and synchronize database schemas and data... Read more...

SQL Toolbelt 2008: Predominantly an Engineering Task
 The conversion of the Red-Gate tools to be compatible with SQL Server 2008 might not seem, on first... Read more...

SQL Response: The dim sum interview
 Richard Morris met David and Nigel of the SQL Response team, in a dim sum Restaurant in Cambridge. They... Read more...

Writing Efficient SQL: Set-Based Speed Phreakery
 Phil Factor's SQL Speed Phreak challenge is an event where coders battle to produce the fastest code to... Read more...

Beginning SQL Server 2005 Reporting Services Part 1
 Steve Joubert begins an in-depth tour of SQL Server 2005 Reporting Services with a step-by-step guide... Read more...

Ten Common Database Design Mistakes
 Database design and implementation is the cornerstone of any data centric project (read 99.9% of... Read more...

Beginning SQL Server 2005 Reporting Services Part 2
 Continuing his in-depth tour of SQL Server 2005 Reporting Services, Steve Joubert demonstrates the most... Read more...

SQL Server Full Text Search Language Features
 SQL Full-text Search (SQL FTS) is an optional component of SQL Server 7 and later, which allows fast... Read more...

Creating CSV Files Using BCP and Stored Procedures
 Nigel Rivett demonstrates some core techniques for extracting SQL Server data into CSV files, focussing... Read more...

Over 150,000 Microsoft professionals subscribe to the Simple-Talk technical journal. Join today, it's fast, simple, free and secure.

Join Simple Talk