程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> SqlServer數據庫 >> 關於SqlServer >> SQL Server 2008:表值參數的創建和使用

SQL Server 2008:表值參數的創建和使用

編輯:關於SqlServer
 表值參數(Table-valued parameter)是SQL Server 2008的一個新特性,在以前的版本中,沒有辦法把表變量當作一個參數傳遞給存儲過程。微軟在SQL Server2008中引入了表值參數的特性,可以實現這項功能。

  表值參數有兩大優點:一是它不需要為初始的數據加鎖,二是它不會導致語句重新編譯。

  表值參數的創建和使用包括以下步驟:

  1) 創建表類型

  2) 創建一個可將表類型作為參數來接受的存儲過程或函數

  3) 創建表變量並插入數據

  4) 調用該存儲過程和函數,並將表變量作為參數傳遞。

  下面,我們來一步步分解這個創建和使用的過程。首先,我們用以下的DDL SQL語句來創建一個名為“TestDB”的測試數據庫:

  USE[master]
  GO
  IFEXISTS(SELECTnameFROMsys.databasesWHEREname=N'TestDB')
  DROPDATABASETestDB
  GO
  CreatedatabaseTestDB
  go

  接下來我們使用以下的DDL SQL語句來創建一個名為TestLocationTable的表:

  USE[TestDB]
  GO
  IFEXISTS(SELECT*FROMsys.objectsWHEREobject_id=OBJECT_ID(N'[dbo].[TestLocationTable]')ANDtypein(N'U'))
  DROPTABLE[dbo].[TestLocationTable]
  GO
  USE[TestDB]
  GO
  SETANSI_NULLSON
  GO
  SETQUOTED_IDENTIFIERON
  GO
  SETANSI_PADDINGON
  GO
  CREATETABLE[dbo].[TestLocationTable](
  [Id][int]NULL,
  [shortname][char](3)NULL,
  [name][varchar](100)NULL
  )ON[PRIMARY]
  GO
  SETANSI_PADDINGOFF
  GO

  然後,使用以下的DML SQL語句將數據添加到我們上面創建的表中:

  USE[TestDB]
  GO
  insertintoTestLocationTable(Id,shortname,Name)select1,'NA1','NewYork'
  insertintoTestLocationTable(Id,shortname,Name)select2,'NA2','NewYork'
  insertintoTestLocationTable(Id,shortname,Name)select3,'NA3','NewYork'
  insertintoTestLocationTable(Id,shortname,Name)select4,'EU1','London'
  insertintoTestLocationTable(Id,shortname,Name)select5,'EU2','London'
  insertintoTestLocationTable(Id,shortname,Name)select6,'AS1','Tokyo'
  insertintoTestLocationTable(Id,shortname,Name)select7,'AS2','HongKong'
  go

  下一步,我們要創建一個和TestLocationTable表具有相似表結構的表類型(TABLE TYPE),語句如下:

  USE[TestDB]
  GO
  IFEXISTS(SELECT*FROMsys.typesstJOINsys.schemasssONst.schema_id=ss.schema_id
  WHEREst.name=N'OfficeLocation_Tabetype'ANDss.name=N'dbo')
  DROPTYPE[dbo].[OfficeLocation_Tabetype]
  GO
  USE[TestDB]
  GO
  CREATETYPE[dbo].[OfficeLocation_Tabetype]ASTABLE(
  [Id][int]NULL,
  [shortname][char](3)NULL,
  [name][varchar](100)NULL
  )
  GO

  緊接著,我們要創建一個可以將表類型作為一個參數來接受的存儲過程,使用的語句如下:

  USE[TestDB]
  GO
  IFEXISTS(SELECT*FROMsys.objectsWHEREobject_id=OBJECT_ID(N'[dbo].[usp_InsertProdLocation]')ANDtypein(N'P',N'PC'))
  DROPPROCEDURE[dbo].[usp_selectProdLocation]
  GO
  CREATEPROCEDUREusp_InsertProdLocation
  @TVPOfficeLocation_TabetypeREADONLY
  AS
  SETNOCOUNTON
  INSERTINTOTestLocationTableSelectID,shortname,namefrom@TVP
  whereconvert(varchar(10),id)+shortname+namenotin(select
  convert(varchar(10),id)+shortname+namefromTestLocationTable)
  GO

  這個存儲過程將表變量作為導入值接收,並且只插入TestLocationTable中沒有的數據。現在,我們可以嘗試創建一個表變量,並執行上面創建的存儲過程usp_InsertProdLocation,語句如下:

  useTestDB
  go
  DECLARE@TVAS[OfficeLocation_Tabetype]
  INSERTINTO@TV(Id,Shortname,Name)SELECT12,'ME1','Dubai'
  INSERTINTO@TV(Id,Shortname,Name)SELECT13,'ME2','Tehran'
  INSERTINTO@TV(Id,Shortname,Name)SELECT17,'EA1','Bombay'
  INSERTINTO@TV(Id,Shortname,Name)SELECT18,'EA2','Karachi'
  INSERTINTO@TV(Id,Shortname,Name)SELECT3,'NA3','NewYork'
  INSERTINTO@TV(Id,Shortname,Name)SELECT4,'EU1','London'
  execusp_InsertProdLocation@TV
  go

  這時候,我們可以使用以下的TSQL語句從表TestLocationTable查詢所有的數據:

  useTestDB
  go
  select*fromTestLocationTable
  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
  (11row(s)affected)

  從返回的結果,我們可以看到存儲過程usp_InsertProdLocation 插入了表變量@TV中和表TestLocationTable所有不匹配的行。

  我們還可以將表變量傳遞給一個函數。下面我們創建一個簡單的函數,語句如下:

  USE[TestDB]
  GO
  IFEXISTS(SELECT*FROMsys.objects
  WHEREobject_id=OBJECT_ID(N'[dbo].[myfunction]')ANDtypein(N'FN',N'IF',N'TF',N'FS',N'FT'))
  DROPFUNCTION[dbo].[myfunction]
  GO
  createfunctiondbo.myfunction(@TVOfficeLocation_TabetypeREADONLY)
  returnsint
  as
  begin
  declare@iint
  set@i=(SelectCOUNT(*)from@TV)
  return@i
  end

  現在,我們通過創建一個表變量並將該變量作為一個參數傳遞給已創建的函數以調用該函數,語句如下:

  USE[TestDB]
  GO
  DECLARE@TVAS[OfficeLocation_Tabetype]
  INSERTINTO@TV(Id,Shortname,Name)SELECT12,'ME1','Dubai'
  INSERTINTO@TV(Id,Shortname,Name)SELECT13,'ME2','Tehran'
  INSERTINTO@TV(Id,Shortname,Name)SELECT17,'EA1','Bombay'
  INSERTINTO@TV(Id,Shortname,Name)SELECT18,'EA2','Karachi'
  INSERTINTO@TV(Id,Shortname,Name)SELECT3,'NA3','NewYork'
  INSERTINTO@TV(Id,Shortname,Name)SELECT4,'EU1','London'
  selectdbo.myfunction(@TV)
  go

  執行結果如下:

  (1row(s)affected)
  (1row(s)affected)
  (1row(s)affected)
  (1row(s)affected)
  (1row(s)affected)
  (1row(s)affected)
  -----------
  6

  注:上面所演示的腳本都是在SQL Server 2008 CTP6版本上進行編寫並經過測試的。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved