SA0013 : Avoid returning results in triggers

Returning data from triggers is not recommended because applications modifying tables or views typically do not expect results, which can lead to unexpected behavior.

Description

Triggers in SQL Server are special types of stored procedures that automatically execute in response to specific events on a table or view. One common problem is when these triggers inadvertently send results back to the application or user that invoked them. This can cause unexpected behavior in applications that do not expect results to be returned from data modification operations. Therefore, it is crucial to ensure that triggers do not include statements like PRINT, SELECT (without assignment or INTO clause), or FETCH (without assignment) that return data.

Example of a trigger returning data:

SQL
 1CREATE TRIGGER trgAfterUpdate
 2ON YourTable
 3AFTER UPDATE
 4AS
 5BEGIN
 6    -- Problematic PRINT statement
 7    PRINT 'Trigger executed.'
 8
 9    -- Problematic SELECT statement
10    SELECT * FROM inserted;
11END;

This example is problematic because:

  • The PRINT statement outputs text back to the client, confusing applications expecting silent operations.

  • The SELECT statement returns data to the caller, which can disrupt application logic by introducing unexpected result sets.

How to fix

To ensure that triggers do not inadvertently return data to the caller, modify the trigger to suppress output operations.

Follow these steps to address the issue:

  1. Identify and remove any PRINT, SELECT (without INTO clause), or FETCH (without assignment) statements within the trigger that cause output to be returned to the caller.

  2. If the application relies on the trigger returning results, refactor the application logic to eliminate this dependency. This can include retrieving necessary data directly through separate queries rather than using the trigger.

  3. Validate that the modified trigger maintains the intended business logic, focusing on performing its task silently without returning any data to the caller.

For example, modify the trigger as shown below:

SQL
1-- Corrected trigger without output
2CREATE TRIGGER trgAfterUpdate
3ON YourTable
4AFTER UPDATE
5AS
6BEGIN
7    -- Removed problematic statements to ensure no data is returned
8    -- Implement necessary logic here
9END;

Scope

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

Parameters
Name Description Default Value
AllowPrint

The parameter specifies if using PRINT statement inside triggers will be allowed.

no

Remarks

The rule does not need Analysis Context or SQL Connection.

Effort To Fix
3 minutes per issue.
Categories

Performance Rules, Bugs

Additional Information

There is no additional info for this rule.

Example Test SQL
SQL
 1CREATE TRIGGER trg_Test_SA0013
 2ON dbo.TestTable
 3AFTER INSERT
 4AS
 5BEGIN
 6    PRINT 'Row inserted into TestTable';
 7
 8    -- Returning results using SELECT
 9    SELECT * FROM inserted;
10
11    -- Using OUTPUT to return inserted rows
12    INSERT INTO dbo.TestLog (InsertedID)
13    OUTPUT inserted.ID
14    SELECT ID FROM inserted;
15END

Analysis Results
  Message Line Column
1 SA0013 : Avoid returning results in triggers. 6 4
2 SA0013 : Avoid returning results in triggers. 9 4
3 SA0013 : Avoid returning results in triggers. 13 4
See Also

Other Resources