How to use T4 to generate CRUD stored procedures


This article demonstrates how to use SMO and T4 templates to generate CRUD stored procedures in Visual Studio.

Overview

Stored procedures can be used to implement CRUD (Create, Read, Update and Delete) database operations. As Andrew Novick explains in his article “Implementing CRUD Operations Using Stored Procedures” (Part 1 and Part 2), using stored procedures helps to improve application performance, encapsulate SQL code in data access layer, reduce SQL injection vulnerability and prevent casual table browsing and modifications. The idea is to have a “Create” stored procedure that encapsulates INSERT SQL statement, one or more “Read” procedures that encapsulate SELECT statements, “Update” procedure that encapsulates UPDATE statement and “Delete” procedure that encapsulates DELETE statement.

Typically, CRUD stored procedures contain repetitive code and can be generated using information about database schema. Microsoft SQL Server Management Objects (SMO) is one of .NET APIs that can be used for this purpose. The following code demonstrates how to access schema of the Products table in Northwind database on the local computer.

using Microsoft.SqlServer.Management.Smo;
// …
Server server = new Server();
Database database = new Database(server, “Northwind”);
Table table = new Table(database, “Products”);
table.Refresh();
// Here we can access:
//  - table.Columns
//  - table.Indexes
//  …

Having access to table schema via SMO, building a T4 template to generate a stored procedure for it is straightforward:

create procedure [dbo].[<#= table.Name #>_Delete]
<#
    foreach(Column column in table.Columns)
    {
        if (column.InPrimaryKey)
            // …
    }
#>
as
    delete from [dbo
].[<#= table.Name #>]
    where
<# // … #>

While it is possible to generate CRUD stored procedures in standalone SQL scripts, it would be more useful to integrate code generation into existing database development process. Attached source code demonstrates how T4 code generation can be used in database projects of Visual Studio Team Edition for Database Professionals.

Solution ExplorerOne of the challenges of integrating code generation with DB Pro edition is that it places each database object in a separate SQL file. In other words, “Create” and “Update” and “Delete” procedures need to be in their own, separate SQL files. On the other hand, T4 engine supports only one output file per template. This makes generation of “Read” stored procedures based on table indexes more difficult as the number of SQL files needs to change depending on the number of indexes.

Another challenge of integrating T4 with DB Pro edition is that T4 engine integrates into Visual Studio as a TextTemplatingFileGenerator custom tool. Unfortunately, database projects in VS 2005 DB Pro don’t support custom tools. As a workaround, we will use a separate C# project for T4 templates and code generation.

Implementation

In order to run this code, you will need Visual Studio 2005 Standard (or higher) Edition, SQL Server 2005, Northwind sample database and DSL Tools installed on your computer. You may also want to install T4 Editor by Tangible Engineering, which adds IntelliSense and syntax highlighting to Visual Studio text editor for T4 templates. Although having Visual Studio 2005 Team Edition for Database Professionals is optional, it will allow you to automatically verify and run generated SQL scripts.

Attached source code contains the following items.

CrudPot.sln

This solution includes two projects - Northwind and Templates.

Northwind

This folder contains a database project created using Visual Studio Team Edition for Database Professionals. This project was generated by importing Northwind database script.

Templates

This folder contains a C# class library project. This project contains no C# code, only T4 templates. Stored procedure templates are physically located in the “Northwind\Schema Objects\Stored Procedures” folder and added as links to the root of the C# project.

  • DeleteProcedure.tt. This is a T4 template that generates a DELETE stored procedure. Generated procedure defines parameters for the primary key and timestamp columns of the target table.
  • InsertProcedure.tt. This is a T4 template that generates an INSERT stored procedure. Generated procedure defines parameters for all columns of the target table. Parameters for IDENTITY and TIMESTAMP columns are defined in the end of the list as OUTPUT parameters. Generated stored procedure returns actual IDENTITY and TIMESTAMP values generated by the SQL server.
  • UpdateProcedure.tt. This is a T4 template that generates an UPDATE stored procedure. Generated procedure defines parameters for all columns of the target table. Parameter for TIMESTAMP is defined as OUTPUT parameter. Generated stored procedure returns new TIMESTAMP value generated by the SQL server.
  • CommonCrud.tt. This is a T4 template that contains common code “included” by other templates and is not intended to be used directly.

Each template has the following parameters:

  • TableName (required, name of the database table for which templates will generate stored procedures)
  • ConnectionString (required, used to specify database used by templates to find the target table)
  • SchemaName (optional, used to specify name of the schema which contains the target table and will contain the generated stored procedures)

Generated stored procedures implement optimistic concurrency control using TIMESTAMP (a.k.a. ROWVERSION) columns.

Usage

In order to use the attached T4 templates in your own project, follow the steps below.

  • Create an empty C# (or VB) project. This project will contain only T4 templates and will be used for code generation. In the attached example, this project is called Templates.
  • Save copies of CommonCrud.tt, DeleteProcedure.tt, InsertProcedure.tt and UpdateProcedure.tt in the folder where you want to generate SQL script files for CRUD stored procedures. In the attached example, these files are located in the “Northwind\Schema Objects\Stored Procedures” folder because that’s where Northwind database project saves SQL scripts for stored procedures.
  • For each DELETE stored procedure, add a new text file with .tt extension to your template project. Name of this file will determine name of the SQL file it will generate. Modify this file to use DeleteProcedure.tt template and specify ConnectionString, TableName and SchemaName parameters. For example, dbo.Products_Insert.proc.tt contains the following text:

    <#
        this.ConnectionString = “Data Source=.;Initial Catalog=Northwind;Integrated Security=True”;
        this.TableName = “Products”;
    #>
    <#@
    include file=DeleteProcedure.tt#>

    This template generates the following code in dbo.Products_Insert.proc.sql:

    – <autogenerated>
    –   This file is generated from T4 template dbo.Products_Delete.proc.tt.
    –   Any changes made manually will be lost next time this file is regenerated.
    – </autogenerated>
    create procedure [dbo].[Products_Delete]
        @ProductID int,
        @TimeStamp timestamp
    as
    begin
        delete from
    [dbo].[Products]
        where
           
    [ProductID] = @ProductID and
           
    [TimeStamp] = @TimeStamp   
    end

    If you are using Visual Studio Team Edition for Database Professionals, add the generated SQL file your database project. Note that this requires having all template files in the “Schema Objects\Stored Procedures” folder of the database project.

  • Repeat the previous step for INSERT stored procedure. Use InsertProcedure.tt template and see dbo.Products_Insert.proc.tt for example.
  • Repeat the previous step for UPDATE stored procedure. Use UpdateProcedure.tt template and see dbo.Products_Update.proc.tt for example

After changing database schema you can regenerate all stored procedures by selecting your template project in Solution Explorer and clicking “Transform All Templates” button in its toolbar.

If you plan to customize any of the T4 templates, consider adding them to your template project. If the template project and templates are located in different folders, make sure that template files are added to the project as linked items and not copies.

Consider modifying CommonCrud.tt to specify actual connection string and avoid having to do it in the individual .tt files.

If you don’t use and don’t plan to use Visual Studio Team Edition for Database Professionals, consider combining CommonCrud.tt, DeleteProcedure.tt, InsertProcedure.tt and UpdateProcedure.tt to generate a single SQL script file with all three stored procedures.

Known Issues

Current version of the attached templates has the following limitations.

  • Column names with special characters are not supported.
  • Generation of SELECT stored procedures is not supported.
  • Changes made in the database project are not detected until they are applied to the database.

About T4

T4 (Text Template Transformation Toolkit) is a template-based code generation engine. It is available in Visual Studio 2008 and as a download in DSL and GAT toolkits for Visual Studio 2005. T4 engine allows you to use ASP.NET-like template syntax to generate C#, T-SQL, XML or any other text files.

For more information about T4, check out my previous article.

Download

T4 templates and source code used in this article are available for download here.


Write a Comment

Take a moment to comment and tell us what you think. Some basic HTML is allowed for formatting.

Reader Comments

Hello Oleg,

Great Tutorial. I had to modify 2 of the assembly versions for this to work with SQL Server 2008. Also the third assembly needed to be added.

< #@ assembly name="Microsoft.SqlServer.ConnectionInfo, Version=10.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91" #>
< #@ assembly name="Microsoft.SqlServer.Smo, Version=10.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91" #>
< #@ assembly name="Microsoft.SqlServer.Management.Sdk.sfc, Version=10.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91" #>

Thanks,

Mike

Thanks, Mike. I didn’t have a chance to try this with SQL Server 2008 yet.

Is there a specific reason why SELECT stored procedures are not supported?

Matt,

No, just a lack of time. Let me know if you are interested in implementing this. This would be a good code generator to add to the T4 Toolbox.

I am interest on adding SELECT stored-proc based on primary keys. Is there any update on the downloaded code?

What you see is what you get. Sorry. If you are using CRUD procedures and would be interested in finishing implementation of this code generator, I can help you incorporate it in T4 Toolbox.

[…] How to use T4 to generate CRUD stored procedures […]

Is there a way we can modify the existing template for alter procedure?

Thanks

Is this same as Tools4SQL (T4S) Stored Procedure Generator?

Because I am finding lot of differences..

[…] How to use T4 to generate CRUD stored procedures […]