Notes on SQL

Random articles from a puzzled DBA

Overview

One thing everybody should realise, is that SQL Server is a huge product – you’ll never learn all of it. Therefore, you shouldn’t feel embarrassed when you learn something that others around you might take for granted.


Reviewing somebody’s code, I came across a segment of the procedure that made no sense to me. As I knew the person who wrote the code is not generally prone to basic errors, I assumed the issue was with my understanding. Surely enough, I have discovered something that I found quite entertaining – you can update a table via the Common Table Expression (CTE) that is linked to it.

Test Environment

Very simple – one table with three simple entries.

Listing 1: Create a Test Database and a Test Table

CREATE DATABASE Test;
GO

USE Test;
GO

CREATE TABLE dbo.TestTable
(
    ID		INT IDENTITY,
	TestText	VARCHAR(50) NULL
);

GO

INSERT INTO dbo.TestTable
(
    TestText
)
VALUES
('First Entry'),
('Second Entry'),
('Third Entry');
GO

Listing 1: Initial Data

Updating via a CTE

First of all, use a CTE to extract the details from the table. This is all I have used CTEs for in the past – extracting the required data for further processing in subsequent queries.

Listing 2: CTE to Select Data

USE Test;
GO

WITH TestCTE
AS (SELECT ID,
           TestText
    FROM dbo.TestTable)
SELECT TestCTE.TestText
FROM TestCTE;
GO

Figure 2: Results from Listing 2

The starting point

Update Data via a CTE

Now to actually alter a row of data through the CTE.

Listing 3: Change a Table’s Data and Select the Data

WITH TestCTE
AS (SELECT ID,
           TestText
    FROM dbo.TestTable)
UPDATE TestCTE
SET TestCTE.TestText = 'Second Entry Updated'
WHERE TestCTE.ID = 2;

SELECT ID,
       TestText
FROM dbo.TestTable;
GO

Looking at the contents of the table, the required row has been altered.

Figure 3: The Updated Data From Listing 3

Updating a Row

Inserting a New Row via a CTE

As well as updating existing rows, it is also possible to add a row with the CTE.

Listing 4: Insert a Row and Select the Data

WITH TestCTE
AS (SELECT ID,
           TestText
    FROM dbo.TestTable)
INSERT INTO TestCTE
(
    TestText
)
VALUES
('Fourth Entry');

SELECT ID,
       TestText
FROM dbo.TestTable;
GO

Figure 4: The Updated Data From Listing 4

Inserted a Row

Deleting a Row via CTE

And if you can update and insert rows, it should be possible to delete them too.

Listing 5: Delete a Row and Select the Data

WITH TestCTE
AS (SELECT ID,
           TestText
    FROM dbo.TestTable)
DELETE TestCTE
WHERE TestCTE.ID = 1;

SELECT ID,
       TestText
FROM dbo.TestTable;
GO

And in the resultant query, the row with an ID of 1 is no longer there.

Figure 5: The Updated Data From Listing 5

Deleted a Row

Conclusion

I knew that you could manipulate rows via Views, but hadn’t realised that it was also possible via a CTE.

There is a never-ending range of things to learn from SQL Server. If you learn something that you believe is quite basic, don’t feel embarassed. There’s a very good chance that you know something about SQL Server that a lot of others don’t know.

3 thoughts on “Updating Tables via CTE – Basic Examples

  1. Luke Miller's avatar Luke Miller says:

    Thanks for the how to do it. Can you provide a why example? What advantages does it provide?

    1. Steve Hall's avatar Steve Hall says:

      I can’t recall the precise code, so I’ve asked the author for some assistance. If I get a response that is worth repeating, I’ll let you know.

  2. Czeslaw Czapla's avatar Czeslaw Czapla says:

    Thank you so much for posting this. Today I encountered an instance of this pattern (ie: updating table data via CTE that references the table) in some code that I was trying to understand (in preparation for enhancing it). The pattern seemed non-sensical to me, but I knew that the code worked. Your post is exactly what I needed to make sense of this pattern.

Leave a reply to Luke Miller Cancel reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.