实例讲解如何把表格变量传递到存储过程中
传递表值参数
用户经常会碰到许多需要把数值容器而非单个数值放到存储过程里的情况。对于大部分的编程语言而言,把容器数据结构传递到例程里或传递出来是很常见而且很必要的功能。TSQL也不例外。
SQL Server 2000通过OPENXML可以实现这个功能,用户可以把数据存储为VARCHAR数据类型然后进行传递。到了SQL Server 2005,随着 XML数据类型以及XQuery的出现,这个功能变得容易一点。但用户仍然需要对XML数据进行组建和粉碎才能够使用它,因此这个功能使用起来并不简单。SQL Server 2008则能够把表值数据类型传递到存储过程和功能中,从而大大地简化了编程的工作,因为程序员无需再花心思去组建和解析XML数据了。该功能还可以让客户方开发员传递客户方数据表格到数据库中。
怎样传递表格参数?
以销售为例,首先建立一个 my SalesHistory表格,里面包含了产品销售的信息。写以下脚本就可以在数据库里创建你选择的表格:
IF OBJECT_ID('SalesHistory')>0 DROP TABLE SalesHistory; GO CREATE TABLE [dbo].[SalesHistory] ( [SaleID] [int] IDENTITY(1,1) NOT NULL PRIMARY KEY, [Product] [varchar](10) NULL, [SaleDate] [datetime] NULL, [SalePrice] [money] NULL ) GO
建立表值参数第一步是创建确切的表格类型,这一步非常重要,因为这样你就可以在数据库引擎里定义表格的结构,让你可以在需要的时候在过程代码里使用该表格。下面的代码创建 SalesHistoryTableType 表格类型定义:
CREATE TYPE SalesHistoryTableType AS TABLE ( [Product] [varchar](10) NULL, [SaleDate] [datetime] NULL, [SalePrice] [money] NULL ) GO
如果想要查看系统里其他类型的表格类型定义,你可以执行下面这个查询命令,查看系统目录:
SELECT * FROM sys.table_types
我们需要定义用来处理表值参数的存储过程。下面这个程序能够接受指定SalesHistoryTableType类型的表值参数,并加载到SalesHistory中,表值参数在Product列中的值为“BigScreen”:
CREATE PROCEDURE usp_InsertBigScreenProducts ( @TableVariable SalesHistoryTableType READONLY ) AS BEGIN INSERT INTO SalesHistory ( Product, SaleDate, SalePrice ) SELECT Product, SaleDate, SalePrice FROM @TableVariable WHERE Product = 'BigScreen' END GO
传递的表格变量还可以用做任何其他表格的查询数据。
传递表值参数功能的局限性
在传递表值变量到程序中时必须使用 READONLY从句。表格变量里的数据不能做修改——除了修改你可以把数据用于任何其他的操作。另外,你也不能把表格变量用做OUTPUT参数——只能用做input参数。
使用自己的新表格变量类型
首先,要声明一个变量类型SalesHistoryTableType,不需要再一次定义表格结构,因为在创建这个表格类型的时候已经定义过了。
DECLARE @DataTable AS SalesHistoryTableType The following script adds 1,000 records into my @DataTable table variable: DECLARE @i SMALLINT SET @i = 1 WHILE (@i <=1000) BEGIN INSERT INTO @DataTable(Product, SaleDate, SalePrice) VALUES ('Computer', DATEADD(mm, @i, '3/11/1919'), DATEPART(ms, GETDATE()) + (@i + 57)) INSERT INTO @DataTable(Product, SaleDate, SalePrice) VALUES('BigScreen', DATEADD(mm, @i, '3/11/1927'), DATEPART(ms, GETDATE()) + (@i + 13)) INSERT INTO @DataTable(Product, SaleDate, SalePrice) VALUES('PoolTable', DATEADD(mm, @i, '3/11/1908'), DATEPART(ms, GETDATE()) + (@i + 29)) SET @i = @i + 1 END
只要把数据加载到表格变量里,就可以把结构传递到存储过程中。
注意:当表格变量作为参数传递后,表格会在存储在tempdb系统数据库里,而不是传递整个数据集在内存里。因为这样保证高效处理大批量数据。所有服务器方的表格变量参数传递都是通过使用reference调用tempdb中的表格。
EXECUTE usp_InsertBigScreenProducts @TableVariable = @DataTable
想要查询程序是否和预想效果一样,可以执行以下查询来看记录是否已经插入到 SalesHistory表格中:
SELECT * FROM SalesHistory
结论:
虽然SQL Server 2008数据库的参数传递功能的使用还有一些局限性,比如不能修改参数中的数据和把变量用于output,但它已经很大程度的提高了程序性能,它可以减少server往返旅程数、利用表格限制并扩展编程在数据库引擎中的功能。
我怎么在ASP.NET中调用存储过程:
CREATE PROCEDURE dbo.testProcedure_AXASselect userID fromUSERS order by userid desc
注:dbo.testProcedure_AX是你创建的存储过程名,可以改为:AXzhz等,别跟关键字冲突就行了.AS下面就是一条SQL语句,不会写SQL语句的请回避。
怎么在ASP.NET中调用这个存储过程:
public static string GetCustomerCName(ref ArrayList arrayCName,ref ArrayList arrayID) { SqlConnection con=ADConnection.createConnection(); SqlCommand cmd=new SqlCommand("testProcedure_AX",con); cmd.CommandType=CommandType.StoredProcedure; con.Open();try { SqlDataReader dr=cmd.ExecuteReader();while(dr.Read()) {if(dr[0].ToString()=="") { arrayCName.Add(dr[1].ToString()); } } con.Close(); return "OK!"; }catch(Exception ex) { con.Close();return ex.ToString(); } }
注:其实就是把以前:
SqlCommand cmd=new SqlCommand("select userID from USERS order by userid desc",con);
中的SQL语句替换为存储过程名,再把cmd的类型标注为CommandType.StoredProcedure(存储过程)。
写个带参数的存储过程:
CREATE PROCEDURE dbo.AXzhz/*这里写注释*/@startDate varchar(16),@endDate varchar(16) ASselect id from table_AX where commentDateTime>@startDate and commentDateTime<@endDate order by contentownerid DESC
注:@startDate varchar(16)是声明@startDate 这个变量,多个变量名间用【,】隔开.后面的SQL就可以使用这个变量了。
我怎么在ASP.NET中调用这个带参数的存储过程:
public static string GetCustomerCNameCount(string startDate,string endDate,ref DataSet ds){ SqlConnection con=ADConnection.createConnection();//-----------------------注意这一段-------------------------------------------------------------------------------------------------------- SqlDataAdapter da=new SqlDataAdapter("AXzhz",con); para0=new SqlParameter("@startDate",startDate); para1=new SqlParameter("@endDate",endDate); da.SelectCommand.Parameters.Add(para0); da.SelectCommand.Parameters.Add(para1); da.SelectCommand.CommandType=CommandType.StoredProcedure;//------------------------------------------------------------------------------------------------------------------------------- try { con.Open(); da.Fill(ds); con.Close();return "OK"; }catch(Exception ex) {return ex.ToString(); } }
注:把命令的参数添加进去,就可以了。
重新验证SQL命令执行是否成功。
CREATE PROCEDURE dbo.AXzhz/* @parameter1 用户名 @parameter2 新密码*/@password nvarchar(20),@userName nvarchar(20)ASdeclare @err0 intupdate WL_user set password=@password where UserName=@userNameset @err0=@@error select @err0 as err0
注:先声明一个整型变量@err0,再给其赋值为@@error(这个是系统自动给出的语句是否执行成功,0为成功,其它为失败),最后通过select把它选择出来。
那怎么从后台获得这个执行成功与否的值:
下面这段代码可以告诉你答案:
public static string GetCustomerCName() { SqlConnection con=ADConnection.createConnection(); SqlCommand cmd=new SqlCommand("AXzhz",con); cmd.CommandType=CommandType.StoredProcedure; para0=new SqlParameter("@startDate","2006-9-10"); para1=new SqlParameter("@endDate","2006-9-20"); da.SelectCommand.Parameters.Add(para0); da.SelectCommand.Parameters.Add(para1); con.Open();try { Int32 re=(int32)cmd.ExecuteScalar(); con.Close(); if (re==0)return "OK!";elsereturn "false"; }catch(Exception ex) { con.Close();return ex.ToString(); } }
注:就是通过SqlCommand的ExecuteScalar()方法取回这个值。
我要根据传入的参数判断执行哪条SQL语句:
ALTER PROCEDURE dbo.selectCustomerCNameCount@customerID intASif @customerID=-1beginselect contentownerid ,userCName,count(*) as countAll from view_usercomment group by contentownerid,userCName order by contentownerid DESCendelsebeginselect contentownerid ,userCName,count(*) as countAll from view_usercomment where contentownerid=@customerID group by contentownerid,userCName order by contentownerid DESCend
转载于:https://www.cnblogs.com/wangchunming/archive/2011/12/06/2278584.html
实例讲解如何把表格变量传递到存储过程中相关推荐
- php中如何固定表格宽度,实例讲解DataTables固定表格宽度(设置横向滚动条)
当表格的列比较多的时候,可能就需要固定表格的宽度了,默认的100%宽已经不适应了.默认的100%宽要实现改变窗口大小也100%的话,在table元素上添加width="100%", ...
- mysql存储过程变量定义_存储过程中MySQL变量定义和赋值
MySQL变量定义和赋值是我们经常会遇到的问题,下面就为您接受如何在存储过程中MySQL变量定义和赋值,希望对您学习MySQL变量定义方面能有所启迪. 一.MySQL变量的定义 mysql变量定义用d ...
- php mysql 变量赋值_mysql存储过程中变量的定义赋值操作
一.变量的定义 mysql中变量定义用declare来定义一局部变量,该变量的使用范围只能在begin...end 块中使用,变量必须定义在复合语句的开头,并且是在其它语句之前,也可以同时申明多个变量 ...
- mysql 存储过程 用户变量值_mysql:用户变量、系统变量、局部变量(存储过程中的)...
MySQL数据库中的变量分为MySQL系统变量和MySQL用户变量. 一.MySQL用户变量:基于会话变量实现的, 可以暂存值, 并传递给同一连接里的下一条sql使用的变量.当客户端连接退出时,变量会 ...
- 通过transmittable-thread-local源码理解线程池线程本地变量传递的原理
前提 最近一两个月花了很大的功夫做UCloud服务和中间件迁移到阿里云的工作,没什么空闲时间撸文.想起很早之前写过ThreadLocal的源码分析相关文章,里面提到了ThreadLocal存在一个不能 ...
- Activiti工作流从入门到入土:完整Hello World大比拼(Activiti工作流 API结合实例讲解)
文章源码托管:https://github.com/OUYANGSIHAI/Activiti-learninig 欢迎 star !!! 本来想着闲来无事,前面在项目中刚刚用到了工作流 Activit ...
- activiti api文档_【白银人机】Activiti 工作流从入门到入土:完整 hello world 大比拼(API 结合实例讲解)...
点击上方"好好学java",选择"置顶"公众号 重磅资源.干货,第一时间送达 重磅推荐 ① 纯福利 | 公众号资源大汇总,一年才一次! ② 重磅!!2018年 ...
- Activiti工作流从入门到入土:完整Hello World大比拼(Activiti工作流 API结合实例讲解)...
文章源码托管:github.com/OUYANGSIHAI- 欢迎 star !!! 本来想着闲来无事,前面在项目中刚刚用到了工作流 Activiti 框架,写写博客的,但是,事情总是纷纷杂杂,一直拖 ...
- mysql动态变量查询_MySQL将变量传递给动态查询
对不起,如果这是一个基本问题! 直至现在我已经创造了PHP的MySQL查询和跨变量传递SQL调用中是这样的:MySQL将变量传递给动态查询 $myparam = $_GET["id_tbl& ...
最新文章
- 零基础入门学习Python(26)-文件1
- Linux 下Shell脚本删除过期文件
- Oracle数据库的显示提交与隐式提交,针对oracle工具的自动提交机制
- JAVA中protected的作用
- soap rest_这是我对REST的后续工作,是新的SOAP:让我们谈谈原始REST
- 论文盘点:ICCV 2019 Top 20,MobileNetV3居首!
- ps 命令查看进程状态
- 解剖“锋芝恋”,张的婚姻就是谢家处心积虑的一场诈骗?
- 编译原理-词法分析-上下文无关文法
- GB/T 36964-2018《软件工程 软件开发成本度量规范》国家标准正式发布
- iOS-OC-集成PayPal支付方式
- MiniUI日期选择框MonthPicker英文修改为中文
- Mac 谷歌Chrome设置浏览器跨域
- lempel ziv matlab,精讲Lempel-Ziv压缩算法
- 微信小程序跳转公众号图文内容
- and desgin Vue页面,使用watch监视, <a-input>内的值, 自动计算出填入框的值,用vue中watch监听input组件的变化
- java 数据结构和算法 排序
- 自动焊锡机加锡时的注意事项
- Photoshop图层混合模式计算公式大全(转)
- #2.3数理比较与分析