分享
 
 
 

SQL Server 2008表值参数的创建和使用步骤

王朝mssql·作者佚名  2008-06-12
窄屏简体版  字體: |||超大  

表值参数(Table-valued parameter)是SQL Server数据库2008的新特性之一,在以往的版本中,我们没有办法把表变量当作一个参数传递给存储过程。但在微软的SQL Server 2008中引入了表值参数这个特性,它可以实现此类功能。

表值参数有两个明显的优点:

1:不需要为初始的数据加锁。

2:它不会导致语句重新编译。

表值参数的创建和使用包括以下步骤:

(1) 创建表类型

(2) 创建一个可将表类型作为参数来接受的存储过程或函数

(3) 创建表变量并插入数据

(4) 调用该存储过程和函数,并将表变量作为参数传递。

下面,我们来一步步分解这个创建和使用的过程。首先,我们用以下的DDL SQL语句来创建一个名为“TestDB”的测试数据库:

USE [master]

GO

IF EXISTS (SELECT name FROM sys.databases WHERE name = N'TestDB')

DROP DATABASE TestDB

GO

Create database TestDB

go

下面,使用以下的DDL SQL语句来创建一个名为TestLocationTable的表:

USE [TestDB]

GO

IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].

[TestLocationTable]') AND type in (N'U'))

DROP TABLE [dbo].[TestLocationTable]

GO

USE [TestDB]

GO

SET ANSI_NULLS ON

GO

SET QUOTED_IDENTIFIER ON

GO

SET ANSI_PADDING ON

GO

CREATE TABLE [dbo].[TestLocationTable](

[Id] [int] NULL,

[shortname] [char](3) NULL,

[name] [varchar](100) NULL

) ON [PRIMARY]

GO

SET ANSI_PADDING OFF

GO

然后,使用以下的DML SQL语句将数据添加到我们上面创建的表中:

USE [TestDB]

GO

insert into TestLocationTable ( Id, shortname, Name) select 1, 'NA1', 'NewYork'

insert into TestLocationTable ( Id, shortname, Name) select 2, 'NA2', 'NewYork'

insert into TestLocationTable ( Id, shortname, Name) select 3, 'NA3', 'NewYork'

insert into TestLocationTable ( Id, shortname, Name) select 4, 'EU1', 'London'

insert into TestLocationTable ( Id, shortname, Name) select 5, 'EU2', 'London'

insert into TestLocationTable ( Id, shortname, Name) select 6, 'AS1', 'Tokyo'

insert into TestLocationTable ( Id, shortname, Name) select 7, 'AS2', 'HongKong'

go

下面,我们需要创建一个和TestLocationTable表具有相似表结构的表类型(TABLE TYPE),语句如下所示:

USE [TestDB]

GO

IF EXISTS (SELECT * FROM sys.types st JOIN sys.schemas ss ON st.schema_id = ss.schema_id

WHERE st.name = N'OfficeLocation_Tabetype' AND ss.name = N'dbo')

DROP TYPE [dbo].[OfficeLocation_Tabetype]

GO

USE [TestDB]

GO

CREATE TYPE [dbo].[OfficeLocation_Tabetype] AS TABLE(

[Id] [int] NULL,

[shortname] [char](3) NULL,

[name] [varchar](100) NULL

)

GO

接下来,需要创建一个可以将表类型作为一个参数来接受的存储过程,使用的语句如下:

USE [TestDB]

GO

IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].

[usp_InsertProdLocation]') AND type in (N'P', N'PC'))

DROP PROCEDURE [dbo].[usp_selectProdLocation]

GO

CREATE PROCEDURE usp_InsertProdLocation

@TVP OfficeLocation_Tabetype READONLY

AS

SET NOCOUNT ON

INSERT INTO TestLocationTable Select ID, shortname, name from @TVP

where convert(varchar(10),id)+shortname+name not in (select

convert(varchar(10),id)+shortname+name from TestLocationTable)

GO

此存储过程将表变量作为导入值接收,并且只插入TestLocationTable中没有的数据。现在,大家可以尝试创建一个表变量,并执行上面创建的存储过程usp_InsertProdLocation,语句如下所示:

use TestDB

go

DECLARE @TV AS [OfficeLocation_Tabetype]

INSERT INTO @TV (Id, Shortname, Name) SELECT 12, 'ME1', 'Dubai'

INSERT INTO @TV (Id, Shortname, Name) SELECT 13, 'ME2', 'Tehran'

INSERT INTO @TV (Id, Shortname, Name) SELECT 17, 'EA1', 'Bombay'

INSERT INTO @TV (Id, Shortname, Name) SELECT 18, 'EA2', 'Karachi'

INSERT INTO @TV (Id, Shortname, Name) SELECT 3, 'NA3', 'NewYork'

INSERT INTO @TV (Id, Shortname, Name) SELECT 4, 'EU1', 'London'

exec usp_InsertProdLocation @TV

go

此时,可以使用以下的TSQL语句从表TestLocationTable查询所有的数据:

use TestDB

go

select * from TestLocationTable

go

查询的结果:

Id, shortname, name

1, NA1, NewYork

2, NA2, NewYork

3, NA3, NewYork

4, EU1, London

5, EU2, London

6, AS1, Tokyo

7, AS2, HongKong

12, ME1, Dubai

13, ME2, Tehran

17, EA1, Bombay

18, EA2, Karachi

(11 row(s) affected)

从返回的结果看,存储过程usp_InsertProdLocation 插入了表变量@TV中和表TestLocationTable所有不匹配的行。

另外,我们还可以将表变量传递给一个函数。下面创建一个简单的函数,语句如下所示:

USE [TestDB]

GO

IF EXISTS (SELECT * FROM sys.objects

WHERE object_id = OBJECT_ID(N'[dbo].[myfunction]')

AND type in (N'FN', N'IF', N'TF', N'FS', N'FT'))

DROP FUNCTION [dbo].[myfunction]

GO

create function dbo.myfunction (@TV OfficeLocation_Tabetype READONLY)

returns int

as

begin

declare @i int

set @i=(Select COUNT(*) from @TV)

return @i

end

现在,大家可以通过创建一个表变量并将该变量作为一个参数传递给已创建的函数以调用该函数,该语句如下所示:

USE [TestDB]

GO

DECLARE @TV AS [OfficeLocation_Tabetype]

INSERT INTO @TV (Id, Shortname, Name) SELECT 12,'ME1','Dubai'

INSERT INTO @TV (Id, Shortname, Name) SELECT 13,'ME2','Tehran'

INSERT INTO @TV (Id, Shortname, Name) SELECT 17,'EA1','Bombay'

INSERT INTO @TV (Id, Shortname, Name) SELECT 18,'EA2','Karachi'

INSERT INTO @TV (Id, Shortname, Name) SELECT 3,'NA3','NewYork'

INSERT INTO @TV (Id, Shortname, Name) SELECT 4,'EU1','London'

select dbo.myfunction(@TV)

go

执行的结果:

(1 row(s) affected)

(1 row(s) affected)

(1 row(s) affected)

(1 row(s) affected)

(1 row(s) affected)

(1 row(s) affected)

-----------

6

注释:上文中的参考脚本已在SQL Server 2008 CTP6版本上进行编写并已经测试成功。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有