当前位置: 首页 > news >正文

SQL Server 2008 表变量参数(表值参数)用法

表值参数是 SQL Server 2008 中的新参数类型。表值参数是使用用户定义的表类型来声明的。使用表值参数,可以不必创建临时表或许多参数,即可向 Transact-SQL 语句或例程(如存储过程或函数)发送多行数据。

表值参数与 OLE DB 和 ODBC 中的参数数组类似,但具有更高的灵活性,且与 Transact-SQL 的集成更紧密。表值参数的另一个优势是能够参与基于数据集的操作。

(注意:Transact-SQL 通过引用向例程传递表值参数,以避免创建输入数据的副本。)

在 Transact-SQL 中创建和使用表值参数

表值参数具有两个主要部分:SQL Server 类型以及引用该类型的参数。若要创建和使用表值参数,请执行以下步骤:

  1. 创建表类型并定义表结构。
    有关如何创建 SQL Server 类型的信息,请参阅用户定义表类型。有关如何定义表结构的详细信息,请参阅 CREATE TABLE (Transact-SQL)。
  2. 声明具有表类型参数的例程。有关 SQL Server 例程的详细信息,请参阅 CREATE PROCEDURE (Transact-SQL) 和 CREATE FUNCTION (Transact-SQL)。
  3. 声明表类型变量,并引用该表类型。有关如何声明变量的信息,请参阅 DECLARE @local_variable (Transact-SQL)。
  4. 使用 INSERT 语句填充表变量。有关如何插入数据的详细信息,请参阅使用 INSERT 和 SELECT 添加行。
  5. 创建并填充表变量后,可以将该变量传递给例程。

    例程超出作用域后,表值参数将不再可用。类型定义则会一直保留,直到被删除。

若要在 SQL Server Native Client 中使用表值参数,请参阅Table-Valued Parameters (SQL Server Native Client)。

若要在 ADO.NET 中使用表值参数,请参阅 ADO.NET 文档。

优点

表值参数具有更高的灵活性,在某些情况下,可比临时表或其他传递参数列表的方法提供更好的性能。表值参数具有以下优势:

  • 首次从客户端填充数据时,不获取锁。
  • 提供简单的编程模型。
  • 允许在单个例程中包括复杂的业务逻辑。
  • 减少到服务器的往返。
  • 可以具有不同基数的表结构。
  • 是强类型。
  • 使客户端可以指定排序顺序和唯一键。

限制

表值参数有下面的限制:

  • SQL Server 不维护表值参数列的统计信息。
  • 表值参数必须作为输入 READONLY 参数传递到 Transact-SQL 例程。不能在例程体中对表值参数执行诸如 UPDATE、DELETE 或 INSERT 这样的 DML 操作。
  • 不能将表值参数用作 SELECT INTO 或 INSERT EXEC 语句的目标。表值参数可以在 SELECT INTO 的 FROM 子句中,也可以在 INSERT EXEC 字符串或存储过程中。

作用域

就像其他参数一样,表值参数的作用域也是存储过程、函数或动态 Transact-SQL 文本。同样,表类型变量也与使用 DECLARE 语句创建的其他任何局部变量一样具有作用域。可以在动态 Transact-SQL 语句内声明表值变量,并且可以将这些变量作为表值参数传递到存储过程和函数。

安全性

表值参数的权限使用下列 Transact-SQL 关键字来遵循 SQL Server 的对象安全模式:CREATE、GRANT、DENY、ALTER、CONTROL、TAKE OWNERSHIP、REFERENCES、EXECUTE、VIEW DEFINITION 和 REVOKE。

目录视图

若要获取与表值参数关联的信息,可以查询下列目录视图:sys.parameters (Transact-SQL)、sys.types (Transact-SQL) 和 sys.table_types (Transact-SQL)。

表值参数与 BULK INSERT 操作

表值参数的使用方法与其他基于数据集的变量的使用方法相似;但是,频繁使用表值参数将比大型数据集要快。大容量操作的启动开销比表值参数大,与之相比,表值参数在插入数目少于 1000 的行时具有很好的执行性能。

重用的表值参数可从临时表缓存中受益。这一表缓存功能可比对等的 BULK INSERT 操作提供更好的伸缩性。使用小型行插入操作时,可以通过使用参数列表或批量语句(而不是 BULK INSERT 操作或表值参数)来获得小的性能改进。但是,这些方法在编程上不太方便,并且随着行的增加,性能会迅速下降。

表值参数在执行性能上与对等的参数阵列实现相当甚至更好。

下表说明根据插入操作的速度应使用哪种技术。

数据源 服务器逻辑 行数 最佳技术

服务器上带格式的数据文件

直接插入

< 1000

BULK INSERT

服务器上带格式的数据文件

直接插入

> 1000

BULK INSERT

服务器上带格式的数据文件

复杂

< 1000

表值参数

服务器上带格式的数据文件

复杂

> 1000

BULK INSERT

远程客户端进程

直接插入

< 1000

表值参数

远程客户端进程

直接插入

> 1000

BULK INSERT

远程客户端进程

复杂

< 1000

表值参数

远程客户端进程

复杂

> 1000

表值参数

示例

下面的示例使用 Transact-SQL 并演示如何执行以下操作:创建表值参数类型,声明变量来引用它,填充参数列表,然后将值传递到存储过程。

USE AdventureWorks;
GO

/*创建表值参数类型 */
CREATE TYPE LocationTableType AS TABLE 
( LocationName VARCHAR(50)
, CostRate INT );
GO

/* 创建一个过程来获得该表值参数数据 */
CREATE PROCEDURE usp_InsertProductionLocation
    @TVP LocationTableType READONLY
 AS 
    SET NOCOUNT ON
    INSERT INTO [AdventureWorks].[Production].[Location]
           ([Name]
           ,[CostRate]
           ,[Availability]
           ,[ModifiedDate])
        SELECT *, 0, GETDATE()
        FROM  @TVP;
 GO

/*声明一个变量来引用该类型*/
DECLARE @LocationTVP 
AS LocationTableType;

/* Add data to the table variable. */
INSERT INTO @LocationTVP (LocationName, CostRate)
    SELECT [Name], 0.00
    FROM 
    [AdventureWorks].[Person].[StateProvince];

/* 把表变量的数据传递给存储过程 */
EXEC usp_InsertProductionLocation @LocationTVP;
GO

相关文章:

  • Java类加载器加载类顺序
  • UML类图小结
  • 系统动力学软件vensim之指数增长
  • 系统动力学软件vensim学习之一阶负反馈
  • 数字水印学习教程
  • Nature Science 2010-2011年全部期刊下载链接
  • QTE安装汉化添加新程序全过程
  • 努力我可以
  • linux 与 虚拟机共享数据
  • GNU make指南
  • Linux扩展swap分区大小
  • 实现了回写功能---报表工具功能之一
  • 分析两种实现多线程的方式:Thread类和Runnable接口
  • 直接来我的私人博客吧
  • Ado.Net读取Excel常见问题总结
  • canvas绘制圆角头像
  • Druid 在有赞的实践
  • HTTP传输编码增加了传输量,只为解决这一个问题 | 实用 HTTP
  • Java深入 - 深入理解Java集合
  • js中forEach回调同异步问题
  • Linux各目录及每个目录的详细介绍
  • pdf文件如何在线转换为jpg图片
  • Rancher如何对接Ceph-RBD块存储
  • zookeeper系列(七)实战分布式命名服务
  • 计算机常识 - 收藏集 - 掘金
  • 记录:CentOS7.2配置LNMP环境记录
  • 正则学习笔记
  • 自制字幕遮挡器
  • 最近的计划
  • ​软考-高级-信息系统项目管理师教程 第四版【第19章-配置与变更管理-思维导图】​
  • # Swust 12th acm 邀请赛# [ K ] 三角形判定 [题解]
  • #LLM入门|Prompt#2.3_对查询任务进行分类|意图分析_Classification
  • $.ajax()方法详解
  • (NSDate) 时间 (time )比较
  • (附源码)springboot人体健康检测微信小程序 毕业设计 012142
  • (三)docker:Dockerfile构建容器运行jar包
  • (一)RocketMQ初步认识
  • (译)计算距离、方位和更多经纬度之间的点
  • (原)本想说脏话,奈何已放下
  • (转)大道至简,职场上做人做事做管理
  • (转)重识new
  • * CIL library *(* CIL module *) : error LNK2005: _DllMain@12 already defined in mfcs120u.lib(dllmodu
  • ./和../以及/和~之间的区别
  • .NET Core WebAPI中封装Swagger配置
  • .NET 服务 ServiceController
  • .NET/C# 使用反射注册事件
  • .NET开源的一个小而快并且功能强大的 Windows 动态桌面软件 - DreamScene2
  • [ vulhub漏洞复现篇 ] ECShop 2.x / 3.x SQL注入/远程执行代码漏洞 xianzhi-2017-02-82239600
  • []我的函数库
  • [<MySQL优化总结>]
  • [Django ]Django 的数据库操作
  • [GN] DP学习笔记板子
  • [IE编程] WebBrowser控件中设置页面的缩放
  • [JavaWeb]—Spring入门
  • [LeeCode]-Divide Two Integers 不用乘除的除法运算