调用包含临时表的sqlserver存储过程

目录:

1. 问题描述

1.1 所遇问题情况
如:您通过自己写的程序创建了一个临时表,然后调用一个存储过程,对某些表进行一些计算后,将结果存入临时表中,最后查询出临时表的数据。您会发现,在定义数据集时调用存储过程返回的数据是空的。
1.2 问题原因
首先可能是因为您创建的临时表与查询的临时表的数据不在同一个会话中即没有在数据集端定义存储过程,导致数据无法共享;创建和查询的临时表已经在同一会话中,但是在调用前后没有加SET NOCOUNT ONSET NOCOUNT OFF
1.3 解决方案
您可在不改变原来定义好的存储过程的情况下,在FineReport定义数据集时创建临时表(可以是多个),之后再调用存储过程或一般sql语句对表做一定的操作,最后select查询出临时表即可。从而保证,创建临时表、操作临时表、查询临时表在同一个会话中;另外需要在数据集的头和尾分别加入SET NOCOUNT ONSET NOCOUNT OFF
下面以示例讲解FineReport中,使用到存储过程和临时表的创建与使用的方法。其创建的临时表,可分为本地临时表与全局临时表的情况。
本地临时表:仅在当前会话中可见,创建本地临时表名前面有一个编号符(#table_name)
全局临时表:在所有会话中都可见,创建全局临时表名前面有两个编号符(##table_name)

2. 本地临时表和全局临时表的调用

2.1 定义本地临时表
报表数据源的定义,例如如下:
具体代码如下:
SET NOCOUNT ON create table #aa( [id] [int] NOT NULL, [单据类别] [varchar] (20) NOT NULL, [单据编号] [varchar] (20) NOT NULL, ); insert into #aa values(1,'a1','a2') insert into #aa values(2,'b1','b2') insert into #aa values(3,'c1','c2') insert into #aa values(4,'d1','d2') exec dbo.proc_aa select * from #aa SET NOCOUNT OFF 
如上图中,定义过程:
  • 先创建临时表
创建临时表,但因创建临时表时有插入语句,所以必须这里要先添加SET NOCOUNT ON语句。
说明:设置SET NOCOUNT ON 为不返回受影响行数,让数据库端不将影响的行数返回给客户端,否则会报该语句没有返回结果集错误的。下面的创建全局临时表中,亦是如此。
  • 调用存储过程
若您创建的存储过程,是如下的情况:
CREATE PROCEDURE proc_aa AS BEGIN insert into #aa values(5,'a1','a2') insert into #aa values(6,'b1','b2') insert into #aa values(7,'c1','c2') insert into #aa values(8,'d1','d2') END 
如上图中,直接调用存储过程即可。
  • 最后查询临时表
最后再查询临时表。点击这边的这样即是已完成本地临时表的定义,下面就可应用相关数据作报表的操作了。
注:先调用存储过程,再创建临时表,然后在报表中调用的方式是不可行的,这样是取不到本地临时表的。因本地临时表,不能在存储过程中定义之后,再在数据源定义中通过语句调用。因此时是属于不同的会话,所以需先创建临时表。
2.2 定义全局临时表
报表数据源的定义,例如如下:
具体代码如下:
SET NOCOUNT ON drop table ##bb create table ##bb( [id] [int] NOT NULL, [单据类别] [varchar] (20) NOT NULL, [单据编号] [varchar] (20) NOT NULL, ); insert into ##bb values(1,'a1','a2') insert into ##bb values(2,'b1','b2') insert into ##bb values(3,'c1','c2') exec dbo.proc_bb select * from ##bb SET NOCOUNT OFF 
如上图中,定义过程:
  • 创建临时表
可看到,大致同于上面所讲的本地临时表的定义,只是稍微有点变化。就是在创建临时表前,又多了句drop table 表的形式。
  • 调用其存储过程
若您创建的存储过程,是如下的情况:
CREATE PROCEDURE proc_bb AS BEGIN insert into ##bb values(5,'a1','a2') insert into ##bb values(6,'b1','b2') insert into ##bb values(7,'c1','c2') insert into ##bb values(8,'d1','d2') END 
如上图中,直接调用存储过程即可。
  • 查询临时表
最后再查询临时表。点击这边的这样即是完成了全局临时表的定义,下面就可应用相关数据作报表的操作了。

说明:这种临时表的定义方式比较自由,怎么定义均可,可在存储过程中定义之后再在数据源定义时进行一些修改之类的操作,只是如果定义就要在数据源定义时,写一个drop table 表(如:##bb)语句,因这边只要数据库不关闭就会一直存在的,不能重复创建的。且第一次预览时会报错,因此时drop了一个不存在的表,第二次就会好了。全局临时表一定要在定义之后预览一次的。

附件列表


主题:
标签: 已验证

文档内容仅供参考,如果你需要获取更多帮助,付费/准付费客户请咨询帆软技术支持
关于技术问题,您还可以前往帆软社区,点击顶部搜索框旁边的提问按钮
若您还有其他非技术类问题,可以联系帆软传说哥(qq:1745114201