SA0020 : Always use a column list in INSERT statements |
![]() |
When using an INSERT statement, not specifying the target column list can lead to various issues.

Failing to specify the columns when performing an INSERT operation can pose significant challenges. This oversight makes SQL scripts error-prone, especially when the underlying table structure is modified.
Example of problematic query:
1INSERT INTO Employees VALUES (1, 'John Doe', 'HR');
The above query assumes the table column order remains constant. If a new column, say ‘Email’, is added at the beginning, this query could fail or insert incorrect data.
-
Potential for data integrity issues or runtime errors if table structure changes (e.g., adding or dropping columns).
-
Decreased code maintainability, as assumptions about the column ordering increase the risk of errors.

Explicitly specify the target column list in the INSERT statement to ensure code resilience and maintainability.
Follow these steps to address the issue:
-
Identify the target table and examine its column schema using SSMS or by querying the INFORMATION_SCHEMA.COLUMNS view.
-
List all columns explicitly in the INSERT statement that will receive data, ensuring they match the order of values provided.
-
Adjust the VALUES list to correspond with the specified column order, respecting data types and constraints.
Example of corrected query:
1INSERT INTO Employees (EmployeeID, Name, Department) 2VALUES (1, 'John Doe', 'HR');

The rule has a Batch scope and is applied only on the SQL script.

Name | Description | Default Value |
---|---|---|
IgnoreTempTargetTables |
Ignore targets that are temporary tables or table variables. |
yes |

The rule requires Analysis Context. If context is missing, the rule will be skipped during analysis.


Design Rules, Code Smells

There is no additional info for this rule.

SQL
1CREATE PROCEDURE HumanResources.uspGetEmployees 2 @LastName nvarchar(50), 3 @FirstName nvarchar(50), 4 @JobTitle nvarchar(50), 5 @Department nvarchar(50) 6AS 7 8 SET NOCOUNT ON; 9 10 -- Target columns are not provided 11 INSERT INTO HumanResources.vEmployeeDepartment 12 VALUES (@FirstName,@LastName,@JobTitle,@Department) 13 14 INSERT INTO #EmployeeDepartment 15 VALUES (@FirstName,@LastName,@JobTitle,@Department) 16 17 -- Target columns are explicitly provided 18 INSERT INTO HumanResources.vEmployeeDepartment(FirstName, LastName, JobTitle, Department) 19 VALUES (@FirstName,@LastName,@JobTitle,@Department) 20 21 INSERT INTO HumanResources.vEmployeeDepartment /*IGNORE:SA0020*/ 22 VALUES (@FirstName,@LastName,@JobTitle,@Department) |

SQL
1CREATE PROCEDURE HumanResources.uspGetEmployees 2 @LastName nvarchar(50), 3 @FirstName nvarchar(50), 4 @JobTitle nvarchar(50), 5 @Department nvarchar(50) 6AS 7 8 SET NOCOUNT ON; 9 10 -- Target columns are not provided 11 INSERT INTO HumanResources.vEmployeeDepartment (BusinessEntityID, Title, FirstName, MiddleName, LastName, Suffix, JobTitle, Department, GroupName, StartDate) 12 VALUES (@FirstName,@LastName,@JobTitle,@Department) 13 14 INSERT INTO #EmployeeDepartment 15 VALUES (@FirstName,@LastName,@JobTitle,@Department) 16 17 -- Target columns are explicitly provided 18 INSERT INTO HumanResources.vEmployeeDepartment(FirstName, LastName, JobTitle, Department) 19 VALUES (@FirstName,@LastName,@JobTitle,@Department) 20 21 INSERT INTO HumanResources.vEmployeeDepartment /*IGNORE:SA0020*/ 22 VALUES (@FirstName,@LastName,@JobTitle,@Department) |

Message | Line | Column | |
---|---|---|---|
1 | SA0020 : Always use a column list in INSERT statements. | 11 | 1 |
