TSQL Coding Standards Checklist
TSQL Coding Standards Checklist
http://teamsites.corp.seic.com/tsu/eDelivery/dballey/standards/Wiki %20Pages/TSQL%20Coding%20Standards%20Checklist.aspx This summarized checklist of SEI TSQL standards must be followed when developing TSQL code for SEI applications. Each developer should submit a copy of this checklist to the relevant project manager for each development assignment and only after coding, unit testing, and this TSQL checklist are complete. This is to be done as confirmation that all SEI coding standards have been adhered to for all TSQL code developed for SEI. A Note About Legacy Code: One of the challenges here at SEI is that there is a great deal of so-called "legacy" code present in our systems, which may or may not meet the standards described in this Wiki. While we do not expect development teams to correct all code present, we do expect that any time a stored procedure is modified or enhanced in any way, that it will be brought up to current standards. Items that will be looked at in particular include error handling and performance optimization. The DBA team reserves the right to deem issues with presented code as "show-stoppers", meaning that a release cannot go forward until an issue is remediated and signed off. We sincerely appreciate the cooperation of our development teams in this effort as we work to ensure SEI's systems are running at peak efficiency. Each developer need to make sure their code adheres to the following standards; A New Application is following the application Access standards to minimize the attack surface area Naming conventions The right data types Normalized tables up to 3NF A narrow, incrementing primary key for each new schema The right indexes All tables contain, at minimum, a primary key and a clustered index. Table variables are exempt from this requirement. Any deviation from this requirement must be explained and approved. Table relationships enforced via foreign key constraints Constraints, defaults and referential integrity maintained where applicable Queries are sargable Checking the execution plan, statistics and relative performance information No rookie mistakes, like hard coding values and failing to format the code Handling errors properly Avoiding cursors if possible No Dynamic SQL unless used for the right reasons No Ad-Hoc statements unless built using prepared statements Adequate number of comments to explain what was intended Avoiding practices that cause stored procedure recompilations Short transactions Data type conversions are avoided Avoiding SELECT * and INSERT without column names WHERE clauses are restricted to prevent too many rows for the application
Stored Procedures
A PRINT statement displaying the object name being compiled must be included in each stored procedure A DROP object statement must be included in each stored procedure Stored procedures are called with the owner qualification to avoid Compile locks on the SP and blocking in high traffic systems Stored procedure headers must include the following: o Stored procedure name o Purpose o Detailed Description o Database o Dependent Objects o Called By Application Name o Upstream Systems\Databases o Downstream Systems\Databases o Revision History o Revision Number o Change Management Request or Ticket Number o Date o Developer o Change Summary NOCOUNT ON for all stored procedures All local variables must be declared and set at the top of the stored procedure Domain data must be referenced by the primary key value rather than the related name, code or description Create statements for temporary tables must come directly after the variable declaration statements in a stored procedure A GO statement and one or more blank lines must follow the end of procedure code and prior to the GRANT statement When executing a stored procedure explicitly name the parameters and assign the appropriate values in the EXECUTE statement As you review the code, make sure you do not see any of the following: o Unnecessary JOINs o Inaccurate calculations or functions o Unnecessary data o Cartesian product
Capitalization
SQL Server functions and reserved keywords (including data types) must be specified in UPPER CASE. System tables and system stored procedures must be specified in lower case. SEI permanent tables and their columns must be specified in Mixed Case. SEI permanent application tables (and their columns) that hold temporary data must be specified in lower case. User created stored procedures, triggers, temporary tables (#table_name) and their columns, local variables and parameters (@variable_name), user-defined data types and table aliases must be specified in lower case. Server names must be specified in UPPER CASE.
Indentation
SQL statements contained inside an IF or a WHILE statement must be indented four spaces; TABS must not be used for indentation. BEGIN and END statements must not be indented and must be left justified with any IF or WHILE statement on previous line. Keywords must be right justified against the end of the first word of the statement. Commas must be at the start of the line for all lists, including lists of columns specified in a SELECT statement.
Comments
Comment the overall code and explain what the code is doing in simple terms so that any DBA\Developer looking at the T-SQL code has an idea of what the code is trying to accomplish. Comment all of the major code blocks of the code and the critical minor points that can be easily overlooked such as a obscure WHERE clause Two hyphens (--), the SQL-92 standard comment indicator, must be used for all comments. Block comments should be used for each set of related SQL statements. Block comments must be used to define the usage of all temporary tables. End of line comments may be used to describe stored procedure parameters or variables. END statements must include a comment which identifies the related IF or WHILE statement when the IF or WHILE statement applies to multiple SQL statements. Specific reasons for not following coding standards must be documented in block comments. As the code is updated reference the applicable revision number to correlate the comments Before promoting the code, update the summary and inline comments to make sure all team members will be able to functionally understand the code based on the comments
Queries
Table aliases must only be used if needed to distinguish a table or view in a self-join or sub-query. In these cases, the table alias name must be descriptive; that is, an acronym and not an abbreviation, and the table alias must specify whether the table is the _inner or _outer table in the self-join or sub-query. The SELECT INTO statement must not be used. Table's must be fully qualified with owner name and/or schema name. JOINS of more than 5 tables must be justified with a documented performance analysis. Queries should make use of existing indexes where possible, especially for large tables and queries with high selectivity. SSMS (SQL Server Management Studio) should be used to analyze the execution plan, its usage, and to suggest the modification of existing TSQL syntax and/or the creation of new indexes as necessary. as new queries are written, columns are added or removed, validate that your indexes will support your performance needs. Validate that indexes are not unnecessarily duplicated and validate as indexes are added that the intended queries take advantage of the query. Validate the following items: Table scanning is not occurring Bookmark lookups are not occurring Code or indexes can be changed to convert index scans to index seeks The use of TEMPDB must be avoided except when creating a temporary table. No more than three levels of nested IF statements may be used. Use a CASE statement instead of multiple nested IF statements when possible. The use of cursors in application code should be justified with performance analysis. Always make use SET based logic as opposed to a cursor or a while statement.
Transactions
Only use BEGIN TRANSACTION, COMMIT TRANSACTION, and ROLLBACK TRANSACTION statements when performing data modifications. The smallest amount of code possible, i.e. the fewest SQL statements, must exist within a transaction; all data preparation must be done outside the scope of the transaction; only statements that modify data on permanent application tables (INSERT, UPDATE and DELETE) require explicit transactions to be used. Error handling must be done after each statement that modifies data (INSERT, UPDATE and DELETE) whether or not the command is issued in the context of an explicit transaction, that is, where COMMIT and ROLLBACK commands must be called. Concurrency checking must be done in conjunction with UPDATE statements on permanent application tables only. When appropriate, the transaction isolation level should be set to read uncommitted for all reporting stored procedures using the SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED command.
Date Values
All local date variables must be declared as DATETIME rather than as SMALLDATETIME. All calendar year values must be represented as four characters (CCYY), e.g. 1999, 2000. All CONVERT functions for DATETIME data types must use formats that support four-year date characters (CCYY). All constant value dates must stipulate the century as part of the date value, e.g., 10/30/70' must be specified as 10/30/1970.
does make sure that you qualify rows the same way that you delete them. Many times there are complex qualifications and this is a way to catch problems in qualification logic such as nulls and other conditions. 2. When executing destructive cleanups, have the qualification clauses reviewed by multiple people to try to catch the problems. 3. If possible, capture the applicable production tables into a dev/qa area to test the scripts. If this is not possible, generate test data that is representative of the production ranges, not necessarily the volume, and test. 4. The normal destructive cleanup process should be: 1. Dump the database 2. Run the cleanup script which contains the select count with qualification and the delete or update with the same qualification. 3. Compare the counts and if they are not the same, rollback, otherwise commit.
In general, one of the big items that are overlooked when it comes to deploying code is a rollback plan. You should always plan for the worst and be prepared if a problem does arise. Inverse Code - Be sure to have code to rollback the code deployment. For example, if you have CREATE code, have the corresponding DROP code. If you are ALTERing an object, have the original code to roll back to that version. Testing - Test the code to validate that it parses correctly and will rollback the code if an unforeseen issue arises. Record Error - If the code face's an unexpected issue, record the error in order to troubleshoot the issue. Rollback - If an issue arises and it is not something that cannot be easily changed, then rollback the code to the original state o Detailed guidelines about how to structure a deployment package are available here. Any deviation from these standards must be explicitly agreed upon by the SQL SME and production DBA teams.
Deployment Scripts