表值变量在批量操作中的用法:
以更新地区的排序值为例子:
创建表值变量的方法:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
1 CREATE TYPE Ty_UpdateAreaInfoShowOrder as Table 2 ( 3 [ID] int primary key not null, 4 [ShowOrder] int null 5 )
在存储过程中做批量操作的例子:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
CREATE PROC USP_UpdateAreaInfoShowOrder @dt Ty_UpdateAreaInfoShowOrder readonly AS BEGIN DECLARE @ERRORSUM SMALLINT =0 BEGIN TRAN SET @ERRORSUM=-1; UPDATE m SET M.ShowOrder = d.ShowOrder FROM MD_AreaInfo m ,@dt d where m.ID = d.ID IF(@@ERROR<>0) GOTO ERROR_HANDLE; COMMIT TRAN; RETURN 0 ERROR_HANDLE: ROLLBACK TRAN; RETURN @ERRORSUM; END
可以看到存储过程的传入参数的表值变量类型(上面所定义的表值变量)
调用存储过程的方法:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
1 public void BindGrid() 2 { 3 using (SqlConnection conn = new SqlConnection(ConnectionString)) 4 { 5 using (SqlCommand cmd = conn.CreateCommand()) 6 { 7 cmd.CommandText = "SELECT [ID], [CnName],[EnName],[ShowOrder] FROM MD_AreaInfo where Parentid=0 ORDER BY SHOWORDER "; 8 DataSet ds = new DataSet(); 9 SqlDataAdapter da = new SqlDataAdapter(cmd); 10 da.Fill(ds); 11 this.gv.DataSource = ds.Tables[0]; 12 this.gv.DataBind(); 13 } 14 } 15 } 16 public DataTable CreateTable() 17 { 18 DataTable dt = new DataTable(); 19 dt.Columns.Add("ID", typeof(int)); 20 dt.Columns.Add("ShowOrder", typeof(int)); 21 return dt; 22 } 23 protected void btn_Click(object sender, EventArgs e) 24 { 25 DataTable dt = CreateTable(); 26 for (int i = 0; i < gv.Rows.Count; i++) 27 { 28 HiddenField hd = (HiddenField)gv.Rows[i].FindControl("hdID"); 29 TextBox tb = (TextBox)gv.Rows[i].FindControl("txtShowOrder"); 30 DataRow dr = dt.NewRow(); 31 dr[0] = int.Parse(hd.Value); 32 dr[1] = int.Parse(tb.Text.Trim()); 33 dt.Rows.Add(dr); 34 } 35 RunStore("USP_UpdateAreaInfoShowOrder", dt); 36 BindGrid(); 37 } 38 public int RunStore(string storeName, DataTable dt) 39 { 40 using (SqlConnection conn = new SqlConnection(ConnectionString)) 41 { 42 conn.Open(); 43 using (SqlCommand cmd = conn.CreateCommand()) 44 { 45 cmd.CommandText = storeName; 46 cmd.CommandType = CommandType.StoredProcedure; 47 SqlParameter sp = new SqlParameter("@dt", SqlDbType.Structured); 48 sp.TypeName = "Ty_UpdateAreaInfoShowOrder"; 49 sp.Value = dt; 50 cmd.Parameters.Add(sp); 51 return cmd.ExecuteNonQuery(); 52 } 53 } 54 return 0; 55 }
表值参数是 SQL Server 2008 中的新参数类型。表值参数是使用用户定义的表类型来声明的。使用表值参数,可以不必创建临时表或许多参数,即可向 Transact-SQL 语句或例程(如存储过程或函数)发送多行数据;
表值参数具有更高的灵活性,在某些情况下,可比临时表或其他传递参数列表的方法提供更好的性能。表值参数具有以下优势:
- 首次从客户端填充数据时,不获取锁。
- 提供简单的编程模型。
- 允许在单个例程中包括复杂的业务逻辑。
- 减少到服务器的往返。
- 可以具有不同基数的表结构。
- 是强类型。
- 使客户端可以指定排序顺序和唯一键。
限制
-
表值参数有下面的限制:
- SQL Server 不维护表值参数列的统计信息。
- 表值参数必须作为输入 READONLY 参数传递到 Transact-SQL 例程。不能在例程体中对表值参数执行诸如 UPDATE、DELETE 或 INSERT 这样的 DML 操作。
- 不能将表值参数用作 SELECT INTO 或 INSERT EXEC 语句的目标。表值参数可以在 SELECT INTO 的 FROM 子句中,也可以在 INSERT EXEC 字符串或存储过程中。
注SqlParameter的SqlDbType定义为SqlDbType.Structured;
TypeName为你所定义表值类型名
value 为 构建的新的内存中的表
举个例子,创建表值变量![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
1 --------------------------------------------------------- 2 ----创建表值变量Ty_ProductionLocation-------------------- 3 --------------------------------------------------------- 4 CREATE TYPE Ty_ProductionLocation AS TABLE( 5 Name NVARCHAR(50) NOT NULL, 6 CostRate smallmoney NOT NULL, 7 Availability DECIMAL(18,4) NOT NULL 8 ) 9 --------------------------------------------------------- 10 ----创建存储过程usp_AddProductLocation------------------- 11 --------------------------------------------------------- 12 CREATE PROC usp_AddProductLocation 13 @dt Ty_ProductionLocation READONLY 14 AS 15 BEGIN 16 SET NOCOUNT ON; 17 DECLARE @ERRORSUM SMALLINT; 18 BEGIN TRAN; 19 SET @ERRORSUM =-1; 20 INSERT INTO Production.Location(Name,CostRate,Availability,ModifiedDate) 21 SELECT tt.*,GETDATE() FROM @dt tt; 22 IF(@@ERROR<>0) GOTO ERROR_HANDLE; 23 COMMIT TRAN; 24 RETURN 0; 25 ERROR_HANDLE: 26 ROLLBACK TRAN; 27 RETURN @ERRORSUM; 28 END 29 ---------------------------------------------------------- 30 --------调用usp_AddProductLocation存储过程---------------- 31 ---------------------------------------------------------- 32 DECLARE @dtt Ty_ProductionLocation; 33 INSERT INTO @dtt(Name,CostRate,Availability) SELECT Name,0,0 FROM Person.StateProvince; 34 EXEC usp_AddProductLocation @dtt
可以看到,创建表值变量类型,声明变量来引用它,然后给变量填充数据,然后将值传递给存储过程.