Using Table-Valued Parameters to Update Multiple Rows

Update many values in thousands of records

What is in this article?:

  • Using Table-Valued Parameters to Update Multiple Rows
Downloads
128864.zip

In previous versions of SQL Server, if I needed to update numerous rows of data, I used a temporary table. Suppose, for example, that thousands of transactions needed their transaction dates updated. I would upload the transaction IDs with the new date value in a temporary table, add a join between the transaction table and the temporary table, and update the transaction table with the new values from the temporary table.   

Although it seemed relatively simple to update thousands of records with temporary tables, what if I had thousands of transactions that needed multiple field values updated? Or what if the updating became a regular request and the company needed to have the functionality available in the application? The process would be difficult to implement and would have a performance impact on the database. With table-valued parameters, available in SQL Server 2008, the update process is easy to implement and has little performance impact on the database. Table-valued parameters can be passed as read-only input parameters. Because transaction logs are not recorded for table-valued parameters, performance improves. Previously, when multiple values were involved, the insert statement was executed multiple times; now, I use a table-valued parameter—with numerous values—that’s treated as one value and requires only one insert statement. The reduced number of trips between client and server boosts performance.

Creating and Using Table-Valued Parameters in T-SQL

A table-valued parameter is a new type of stored-procedure capability available in SQL Server 2008. Basically, a table-valued parameter lets you use an array of data in T-SQL, as well as send an entire data-set table as a parameter in a stored procedure or function. SQL Server 2008 stores this parameter as a user-defined table type. You can also add primary key and unique constraints to the table type.

The ddl_script.sql in Listing 1 sets up the test database MovieRentalDB with a table and the table type. Additionally, it populates the table with values.

Listing 1: Code to Populate MovieRentalDB with a Table and Table Type<p style="margin-bottom: 8px;">CREATE DATABASE \\[MovieRentalDB\\]</p><br><p style="margin-bottom: 8px;">USE MovieRentalDB</p><br><p style="margin-bottom: 8px;">CREATE TABLE TransLog(</p><br><p style="margin-bottom: 8px;">TransID int IDENTITY(101,1) PRIMARY KEY not null,</p><br><p style="margin-bottom: 8px;">UserID int not null,</p><br><p style="margin-bottom: 8px;">TransDate date not null,</p><br><p style="margin-bottom: 8px;">TypeID int not null)</p><br><p style="margin-bottom: 8px;">CREATE TYPE dbo.ChangeTransDate AS TABLE(</p><br><p style="margin-bottom: 8px;">            TransID varchar(36) NOT NULL,</p><br><p style="margin-bottom: 8px;">            NewDate datetime NOT NULL)</p><br><p style="margin-bottom: 8px;">INSERT INTO TransLog VALUES(1,'8/8/2009',1)</p><br><p style="margin-bottom: 8px;">INSERT INTO TransLog VALUES(2,'8/8/2009',2)</p><br><p style="margin-bottom: 8px;">INSERT INTO TransLog VALUES(3,'8/8/2009',3)</p><br><p style="margin-bottom: 8px;">INSERT INTO TransLog VALUES(4,'8/8/2009',4)</p><br><p style="margin-bottom: 8px;">INSERT INTO TransLog VALUES(5,'8/8/2009',5)</p>

 

The three steps that follow, each with its code segment, let you see how to create and execute table-valued parameters in T-SQL. First, with the code segment below, you create a new user-defined table type.

 

--Create new table type to use as a table-value parameter<p style="margin-bottom: 8px;">CREATE TYPE dbo.ChangeTransDate AS TABLE(</p><br><p style="margin-bottom: 8px;">            TransID varchar(36) NOT NULL,</p><br><p style="margin-bottom: 8px;">            NewDate datetime NOT NULL)</p>


Second, you create a stored procedure with a table-valued parameter, as Listing 2 shows. Third, you execute the stored procedure, as Listing 3 shows. Figure 1 shows the results of the insert statement in Listing 3.

Listing 2: Code to Create Stored Procedure<p style="margin-bottom: 8px;">--Create procedure to update many rows</p><br><p style="margin-bottom: 8px;">CREATE PROCEDURE \\[dbo\\].\\[UpdateTransactionDates\\]</p><br><p style="margin-bottom: 8px;">            @TableParam ChangeTransDate READONLY</p><br><p style="margin-bottom: 8px;">AS</p><p style="margin-bottom: 8px;"> </p><p style="margin-bottom: 8px;">UPDATE b SET b.TransDate = a.NewDate</p><br><p style="margin-bottom: 8px;">FROM @TableParam a</p><br><p style="margin-bottom: 8px;">JOIN TransLog b ON b.TransID=a.TransID</p>

 

Listing 3: Code to Execute Stored Procedure<p style="margin-bottom: 8px;">--Add the table-value parameter and call the stored procedure<br>DECLARE @NewTableParam ChangeTransDate</p><br><p style="margin-bottom: 8px;">INSERT INTO @NewTableParam(TransID,NewDate)</p><br><p style="margin-bottom: 8px;">VALUES (101,'1/10/2009'),(102,'2/10/2009'),</p><br><p style="margin-bottom: 8px;">(103,'3/10/2009'),(104,'4/10/2009'),(105,'5/10/2009')</p><br><p style="margin-bottom: 8px;">EXEC dbo.UpdateTransactionDates @TableParam = @NewTableParam</p><br><p style="margin-bottom: 8px;">--Select from the table to verify the change</p><br><p style="margin-bottom: 8px;">SELECT * FROM TransLog</p>

 

Note: The storedprocedure_script.sql is the insert procedure that passes the table-valued parameter with the matthewharrisapplication. Book3.csv, which you can download, is an example comma-delimited file of the values that will be passed with the stored procedure. Matthewharrisapplication is developed in C# and is also available for download. The application will work if the database is created on the local server. If not (if the database is created on a different instance of SQL Server than local server), SQLConnection will have to be changed. 

 

 »

Discuss this Article 4

60061446
on Jan 6, 2011
Hi Matthew, nice article.

We've been using table valued parameters, but we experience problems when the table type is defined with a column with an identity.

Do you know a solution for this ?

Best Regards,

Franky
shishirk
on Dec 6, 2010
Good article, Matthew. We, although' have been bitten by this feature where the database performance does get affected. When you use TVPs in SQL Server the batch that is generated for SQL Server to execute looks something like this:

Declare @T TABLE(col1 int)
insert into @T (1)
insert into @T (2)
insert into @T (3)
insert into @T (4)

exec procA @TVP = @T

The problem is in the part before the actual "exec procA" part. If the number of values being populated in the .NET data table are very high (tens of thousands in our case), it degrades performance of the server due to high number of complilation and possibly plan cache bloating too. We have also seen CPU going high during several concurrent calls of similar nature. Although the high CPU cannot be attributed to just the use of TVPs, it definitely constitutes a better part of the high CPU numbers.

Regards
Shishir Khandekar
shishirk
on Dec 6, 2010
Good article, Matthew. We, although' have been bitten by this feature where the database performance does get affected. When you use TVPs in SQL Server the batch that is generated for SQL Server to execute looks something like this:

Declare @T TABLE(col1 int)
insert into @T (1)
insert into @T (2)
insert into @T (3)
insert into @T (4)

exec procA @TVP = @T

The problem is in the part before the actual "exec procA" part. If the number of values being populated in the .NET data table are very high (tens of thousands in our case), it degrades performance of the server due to high number of complilation and possibly plan cache bloating too. We have also seen CPU going high during several concurrent calls of similar nature. Although the high CPU cannot be attributed to just the use of TVPs, it definitely constitutes a better part of the high CPU numbers.

Regards
Shishir Khandekar
60061446
on Jan 6, 2011
Hi Matthew, nice article.

We've been using table valued parameters, but we experience problems when the table type is defined with a column with an identity.

Do you know a solution for this ?

Best Regards,

Franky

Please or Register to post comments.

IT/Dev Connections

Las Vegas
September 30th - October 4th

Paul ThurottOur Experts will show you:
• Common SQL Server
Problems
• Best Practices for T-SQL
• SQL Server Integration
Services
• Database Development

Come See Mike Otey & Tim Ford in Person!

Early Registration Now Open

From the Blogs
May 9, 2013
blog

My ISO 8601-Compliant Signature 2

My family recently just "officially" announced that we're in the process of adopting a child from South Africa. We're quite excited, of course, but there's a ton of paperwork to do—along with the need for gobs of signatures....More
May 8, 2013
blog

Use SSIS for ETL from Hadoop

In this blog post, Mark Kromer walks you through using SSIS as a way to use ETL techniques using Microsoft's Hadoop on Windows (HDInsight) as a source using Hive connectors...More
Vision road sign
May 6, 2013
blog

Cheaters Never Win, Even in TPC Benchmarks

In this portion of the series on database benchmarking, I want to tell you about one of my favorite aspects of the TPC benchmarks – CHEATING....More
SQL Server Pro Forums

Get answers to questions, share tips, and engage with the SQL Server community in our Forums.