SQL Server 中的表值型参数

阅读数:1019 2008 年 9 月 2 日

话题:.NETDevOps语言 & 开发

表值型参数(Table-valued parameters)是 SQL Server 2008 中引入的一种新特性,它提供了一种内置的方式,让客户端应用可以只通过单独的一条参化数 SQL 语句,就可以向 SQL Server 发送多行数据。

这一功能的基础是 SQL Server 2008 中最新的用户自定义表类型(User-Defined Table Types),它允许用户将表的定义注册为全局周知类型。注册之后,这些表类型可以像本地变量一样用于批处理中、以及存储过程的函数体中,很像早期 SQL Server 版本中通用表变量的强类型化版本。但是,与通用表变量有所不同的是,用户自定义表类型的变量可以作为参数在存储过程和参数化 TSQL 中使用。



用户自定义表类型的使用有许多限制:

  • 一个用户自定义表类型不允许用来定义表的列类型,也不能用来定义一个用户自定义结构类型的字段。
  • 不允许在一个用户自定义表类型上创建一个非聚合索引,除非这个索引是基于此用户自定义表类型创建的主键或唯一约束。
  • 在用户自定义表类型的定义中,不能指定缺省值。
  • 一旦创建后,就不允许再对用户自定义表类型的定义进行修改。
  • 用户自定义函数不能以用户定义表类型中的计算列定义为参数来调用。
  • 一个用户自定义表类型不允许作为表值型参数来调用用户自定义函数。

当用户自定义表类型作为表值型参数时,还有更多限制,例如,在参数化语句或存储过程中,它们是只读的:

不允许更新多行表值型参数中的列值,也不允许插入或删除行。如果想要修改那些已经传入到存储过程或参数化语句中的表值型参数中的数据,只能通过向临时表或表变量中插入数据来实现。

在 ADO.NET 中,可以利用标准的 SqlParameter 类型来使用用户自定义表类型:

  • TypeName 参数必须设置为用户自定义表类型的名称,例如:dbo.PersonInfo
  • SqlDbType 必须设置为 SqldbType.Structured
  • Value 参数的类型数据必须与用户自定义表类型中的类型相匹配。System.Data.SqlClient 中可以通过 System.Data.DataTable 或 IList 来支持表值型参数。此外,还可以通过 System.Data.Common.DbDataReader 及其派生类(如 OracleDataReader)将多行数据转为流,然后映射到表值型参数。

在表值型参数出现以前,开发者只能使用一些替代方案来模拟它的能力:

  • 使用一连串的独立参数来表示多列和多行数据的值。使用这一方法,可以被传递的数据总量受限于可用参数的个数。SQL Server 的存储过程最多可以使用 2100 个参数。在这种方法中,服务端逻辑必须将这些独立的值组合到表变量中,或是临时表中进行处理。
  • 将多个数据值捆绑到带限定符的字符串或是 XML 文档中,然后再将文本值传递到一个存储过程或语句中。这种方式要求存储过程或语句中要有必要的数据结构验证和数据松绑的逻辑。
  • 为多行数据的修改创建一系列独立的 SQL 语句,就像在一个 SqlDataAdapter 中调用 Update 方法时产生的那些一样,这些更新可以被独立地或是分组成批地提交到服务器。不过,尽管成批提交中含有多重语句,但这些语句在服务端都是被分开独立执行的。
  • 使用 bcp 实用程序或是使用 SqlBulkCopy 对象将多行数据载入一个表中,尽管这一技术效率很高,但它并不支持在服务端执行,除非数据是被载入到临时表或是表变量中。

查看英文原文Table-Valued Parameters in SQL Server