Writing SQL code involves more than simply making it function; it also involves making it comprehensible, maintainable, and audit-friendly. Writing professional SQL code requires careful comments. The advantages of SQL comments, common commenting techniques, and examples for various SQL objects such as tables, procedures, functions, triggers, sequences, and indexes will all be covered in this article.
Why Comment in SQL Code?
Commenting SQL code brings several benefits:
- Improves Readability: Helps developers understand your code without digging into every line.
- Facilitates Maintenance: Makes it easier to fix bugs or enhance features later.
- Audit & Documentation: Useful in enterprise environments for tracking who created or modified objects.
- Reduces Human Error: Helps teams follow standards and avoid mistakes.
- Supports Collaboration: Makes it easier for multiple developers to work on the same database.
Commenting Standards
- A good SQL commenting standard should include:
- Header Block Comments: Metadata about the object: author, date, description, and notes.
- Inline Comments: Explain non-obvious logic or why a piece of code exists.
- Consistency: Same style across all objects (tables, triggers, procedures, etc.).
- Avoid Obvious Comments: Explain why instead of what.
- Audit Information: Optional: who created or modified the object, when, and why.
Effective Commenting for Tables, Functions, Triggers, Indexes, and Sequences
1. Tables
/******************************************************************************************
* Table Name : dbo.Roles
* Description : Stores system roles with audit columns.
* Author : Peter
* Created On : 2025-10-09
* Last Modified: 2025-10-09
* Notes:
* - Includes CreatedBy, CreatedDate, UpdatedBy, UpdatedDate columns for auditing.
******************************************************************************************/
CREATE TABLE dbo.Roles (
RoleId INT IDENTITY(1,1) PRIMARY KEY, -- Unique identifier for the role
RoleName VARCHAR(50) NOT NULL, -- Name of the role
Description VARCHAR(255) NULL, -- Optional description of the role
CreatedBy VARCHAR(100) NULL, -- User who created the record
CreatedDate DATETIME DEFAULT GETDATE(), -- Timestamp when record was created
UpdatedBy VARCHAR(100) NULL, -- User who last updated the record
UpdatedDate DATETIME NULL -- Timestamp when record was last updated
);
Important points
- Use block comments for headers.
- Use inline comments for columns.
- Include author, creation date, and purpose.
2. Functions
/******************************************************************************************
* Function Name : fn_GetRoleName
* Description : Returns the RoleName for a given RoleId.
* Author : Peter
* Created On : 2025-10-09
******************************************************************************************/
CREATE FUNCTION dbo.fn_GetRoleName (@RoleId INT)
RETURNS VARCHAR(50)
AS
BEGIN
DECLARE @RoleName VARCHAR(50);
-- Fetch RoleName from Roles table
SELECT @RoleName = RoleName
FROM dbo.Roles
WHERE RoleId = @RoleId;
RETURN @RoleName;
END;
GO
Always think about where and how the function will be used. If it’s called millions of times in a query, performance optimization is critical
3. Triggers
/******************************************************************************************
* Trigger Name : trg_Update_Roles
* Table Name : dbo.Roles
* Description : Automatically updates UpdatedDate when a record in Roles is modified.
* Author : Peter
* Created On : 2025-10-09
* Last Modified: 2025-10-09
* Notes:
* - UpdatedBy must be set manually.
* - Ensures audit consistency across updates.
******************************************************************************************/
CREATE TRIGGER trg_Update_Roles
ON dbo.Roles
AFTER UPDATE
AS
BEGIN
SET NOCOUNT ON; -- Prevent "rows affected" messages for better performance
BEGIN TRY
-- Update the UpdatedDate to current timestamp for all modified rows
UPDATE r
SET r.UpdatedDate = GETDATE()
FROM dbo.Roles AS r
INNER JOIN inserted AS i ON r.RoleId = i.RoleId;
END TRY
BEGIN CATCH
-- Error handling: raise meaningful error message
DECLARE @ErrorMessage NVARCHAR(4000) = ERROR_MESSAGE();
DECLARE @ErrorSeverity INT = ERROR_SEVERITY();
DECLARE @ErrorState INT = ERROR_STATE();
RAISERROR('Error in trigger trg_Update_Roles: %s', @ErrorSeverity, @ErrorState, @ErrorMessage);
END CATCH;
END;
GO
4. Sequences
/******************************************************************************************
* Sequence Name : seq_OrderId
* Description : Generates unique OrderId for Orders table.
* Author : Peter
* Created On : 2025-10-09
******************************************************************************************/
CREATE SEQUENCE dbo.seq_OrderId
START WITH 1
INCREMENT BY 1;
5. Indexes
/******************************************************************************************
* Index Name : IX_Roles_RoleName
* Table Name : dbo.Roles
* Description : Non-clustered index on RoleName for faster search.
* Author : Peter
* Created On : 2025-10-09
******************************************************************************************/
CREATE NONCLUSTERED INDEX IX_Roles_RoleName
ON dbo.Roles (RoleName);
6. Stored Procedures
/******************************************************************************************
* Procedure Name : sp_GetRoleById
* Description : Retrieves role details by RoleId.
* Author : Peter
* Created On : 2025-10-09
* Last Modified : 2025-10-09
* Parameters:
* @RoleId INT - Role identifier
* Returns:
* Role details from dbo.Roles
******************************************************************************************/
CREATE PROCEDURE dbo.sp_GetRoleById
@RoleId INT
AS
BEGIN
SET NOCOUNT ON; -- Prevent "rows affected" messages
-- Select role information
SELECT RoleId, RoleName, Description, CreatedBy, CreatedDate, UpdatedBy, UpdatedDate
FROM dbo.Roles
WHERE RoleId = @RoleId;
END;
GO
SQL Code Smells & Rules for Tables, Functions, Triggers, Indexes and Sequences
1. Tables
Code Smells
- Poor naming conventions: Table names like tbl1, data, or temp are vague.
- Too many columns: More than 50–100 columns might indicate the table isn’t normalized.
- Unused columns: Columns never queried or used in transactions.
- Repeated data: Indicates denormalization or missing relationships.
- No primary key: Leads to duplicate rows and poor indexing.
- Excessive nullable columns: Hard to enforce data integrity.
Best Practices
- Use clear, singular, meaningful names: Employee, ProductOrder.
- Normalize data to at least 3NF unless justified.
- Always define primary keys and appropriate foreign keys.
- Use data types appropriately: don’t use VARCHAR(255) for small text.
- Limit NULLs; use default values where applicable.
- Add comments to describe table's purpose:
2. Functions
Code Smells
- Functions that do too much (multiple responsibilities).
- Functions that access tables unnecessarily inside loops.
- Functions with side effects (modifying data).
- Poor naming (func1, doSomething).
Best Practices
- Functions should be pure (no side effects).
- One function → one purpose.
- Use a schema prefix to avoid ambiguity.
- Add comments explaining input/output:
3. Triggers
Code Smells
- Triggers that perform complex logic or call other triggers → hard to maintain.
- Silent failures: errors not logged.
- Multiple triggers for the same action → order dependency issues.
- Triggers updating the same table → risk of recursion.
Best Practices
- Keep triggers small and specific.
- Prefer using constraints or stored procedures instead of triggers if possible.
- Log errors and operations.
- Use AFTER vs INSTEAD OF carefully.
4. Indexes
Code Smells
- Too many indexes → slows down writes.
- Unused indexes → waste of storage.
- Non-selective indexes → low performance gain.
- Indexing columns that are frequently updated → high maintenance cost.
Best Practices
- Index frequently queried columns used in WHERE, JOIN, and ORDER BY.
- Avoid indexing columns with low cardinality (like gender).
- Monitor index usage and remove unused indexes.
- Name indexes consistently: IX_Table_Column.
5. Sequences
Code Smells
- Using sequences unnecessarily for small tables.
- Sequences with large gaps → indicate poor management.
- Sequences without ownership or naming standards.
Best Practices
- Use sequences for unique, incremental values across tables.
- Define start, increment, min, mand ax values.
- Always name sequences clearly: SEQ_EmployeeID.
6. Stored Procedures
Common SQL Smells
- Too long / complex procedures – doing multiple unrelated tasks in one SP.
- Hard-coded values – making the procedure inflexible and non-reusable.
- No parameters or overuse of global variables – reduces modularity.
- Missing error handling – errors are swallowed or unlogged.
- Excessive dynamic SQL – may lead to SQL injection or maintenance issues.
- Returning result sets instead of using output parameters when needed – inconsistent usage.
- Tightly coupled logic – SP depends heavily on other SPs or tables, making it hard to maintain.
- Unused or deprecated SPs – bloats the database.
Best Practices
- One procedure, one purpose – keep SPs focused and small.
- Use parameters – avoid hard-coded values; makes SP reusable.
- Error handling – use TRY…CATCH to log or handle errors gracefully.
- Use schema prefix & meaningful names – e.g., usp_InsertEmployee.
- Avoid excessive dynamic SQL – use static queries where possible; if dynamic SQL is needed, validate input.
- Document logic – add comments for inputs, outputs, and special cases.
- Return status codes or output parameters instead of always returning full result sets.
- Use sequences or identity columns appropriately – only when unique incremental IDs are required.
- Avoid unnecessary loops – leverage set-based operations for performance.
- Maintainability – regularly review SPs and remove unused or deprecated ones.
Developers, DBAs, and reviewers can use this document as a reference to keep clean, manageable SQL code and steer clear of performance issues. It is a professional requirement to use proper SQL comments. It enhances auditing, maintainability, and readability. By adhering to these guidelines, you can make sure that your database is reliable, collaborative, and future-proof. While writing code, commenting might take a few extra minutes, but it saves hours on maintenance and debugging.
I appreciate you reading my content. I hope you now have a thorough understanding of SQL Commenting Best Practices: Benefits, Standards & Examples. Although adhering to coding standards and using proper SQL comments may seem insignificant, they have a significant impact on producing database code that is professional, readable, and maintainable. By putting these best practices into practice, you can make sure that your projects are long-lasting, collaborative, and manageable.
Happy coding and keep your SQL Code clean!
HostForLIFE.eu SQL Server 2022 Hosting
HostForLIFE.eu is European Windows Hosting Provider which focuses on Windows Platform only. We deliver on-demand hosting solutions including Shared hosting, Reseller Hosting, Cloud Hosting, Dedicated Servers, and IT as a Service for companies of all sizes.
