Table-valuesparameter(TVP)系列之一:在T-SQL中创建和使用TVP一.摘要表值参数(Table-valuedparameters)简称TVP,是SQLServer2008中引入的一种新特性,它提供了一种内置的方式,让客户端应用可以只通过单独的一条参化数SQL语句,就可以向SQLServer发送多行数据。二.简介在表值参数出现以前,当需要发送多行数据到SQLServer,我们只能使用一些替代方案来实现:(1)使用一连串的独立参数来表示多列和多行数据的值。使用这一方法,可以被传递的数据总量受限于可用参数的个数。SQLServer的存储过程最多可以使用2100个参数。在这种方法中,服务端逻辑必须将这些独立的值组合到表变量中,或是临时表中进行处理。(2)将多个数据值捆绑到带限定符的字符串或是XML文档中,然后再将文本值传递到一个存储过程或语句中。这种方式要求存储过程或语句中要有必要的数据结构验证和数据松绑的逻辑。(3)为多行数据的修改创建一系列独立的SQL语句。就像在一个SqlDataAdapter中调用Update方法时产生的那些一样,这些更新可以被独立地或是分组成批地提交到服务器。不过,尽管成批提交中含有多重语句,但这些语句在服务端都是被分开独立执行的。(4)使用bcp实用程序或是使用SqlBulkCopy对象将多行数据载入一个表中。尽管这一技术效率很高,但它并不支持在服务端执行(注:多行数据仍然无法一次性传给存储过程),除非数据是被载入到临时表或是表变量中。SQLServer2008中的T-SQL功能新增了表值参数。利用这个新增特性,我们可以很方便地通过T-SQL语句,或者通过一个应用程序,将一个表作为参数传给函数或存储过程。(1)表值参数表示你可以把一个表类型作为参数传递到函数或存储过程里。(2)表值参数的功能可以允许你向被声明为T-SQL变量的表中导入数据,然后把该表作为一个参数传递到存储过程或函数中去。(3)表值参数的优点在于你可以向存储过程或函数发送多行数据,而无需向以前那样必须声明多个参数或者使用XML参数类型来处理多行数据。三.描述计划分三部分描述表值参数的应用。(1)在T-SQL中创建和使用TVP(2)在ADO.NET中利用DataTable对象,将其作为参数传给存贮过程(3)在ADO.NET中利用Collection对象,将其作为参数传给存贮过程四.第一部分:在T-SQL中创建和使用TVP参看URL:ms-help://MS.SQLCC.v10/MS.SQLSVR.v10.en/s10de_1devconc/html/5e95a382-1e01-4c74-81f5-055612c2ad99.htm1.表值参数具有两个主要部分:SQLServer类型以及引用该类型的参数,若要创建和使用表值参数,请执行以下步骤:(1)创建表类型并定义表结构。TVP功能的基础是SQL2008中最新的用户自定义表类型(User-DefinedTableTypes),简称UDTT,它允许用户将表的定义注册为全局周知类型。注册之后,这些表类型可以像本地变量一样用于批处理中、以及存储过程的函数体中,也就是UDTT的变量可以作为参数在存储过程和参数化TSQL中使用。用户自定义表类型的使用有许多限制:(1)一个用户自定义表类型不允许用来定义表的列类型,也不能用来定义一个用户自定义结构类型的字段。(2)不允许在一个用户自定义表类型上创建一个非聚合索引,除非这个索引是基于此用户自定义表类型创建的主键或唯一约束。(3)在用户自定义表类型的定义中,不能指定缺省值。(4)一旦创建后,就不允许再对用户自定义表类型的定义进行修改。(5)用户自定义函数不能以用户定义表类型中的计算列定义为参数来调用。(6)一个用户自定义表类型不允许作为表值型参数来调用用户自定义函数。例如:?/*Createauser-definedtabletype*/CREATETYPEOrderItem$UdtASTABLE(OrderIdintprimarykey,CustomerIdint,OrderedAtdatetime)GO(2)声明具有表类型参数的例程。--------------------------?CREATEPROCEDUREOrderItem$Insert(@OrderHeadersASOrderItem$UdtREADONLY,@OrderDetailsASOrderDetail$UdtREADONLY)ASBEGIN--BulkinsertorderheaderrowsfromTVPINSERTINTO[OrderItem]SELECT*,SYSDATETIME()FROM@OrderHeaders--BulkinsertorderdetailrowsfromTVPINSERTINTO[OrderDetail]SELECT*,SYSDATETIME()FROM@OrderDetailsENDGO(3)声明表类型变量,并引用该表类型。---------------------------?IFOBJ...