查看: 5889|回复: 6

[精华] 系统临时表使用问题

[复制链接]
论坛徽章:
75
授权会员
日期:2005-10-30 17:05:332012新春纪念徽章
日期:2012-02-13 15:08:092012新春纪念徽章
日期:2012-02-13 15:08:09ITPUB 11周年纪念徽章
日期:2012-10-09 18:06:20迷宫蛋
日期:2012-12-24 09:08:13茶鸡蛋
日期:2013-01-05 10:22:14咸鸭蛋
日期:2013-02-01 16:50:322013年新春福章
日期:2013-02-25 14:51:24紫蛋头
日期:2013-04-21 13:58:57本田
日期:2013-12-07 19:34:23
跳转到指定楼层
1#
发表于 2006-4-20 20:12 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
系统临时表使用问题

作者:vlife  

系统临时表的使用:
在一些程序中,我们需要一些仅仅在程序中使用的临时表,但是程序结束后就不再使用,数据库系统对这些应用提供系统临时表,关于系统临时表的生命存在周期和临时表的数据存在周期说明一下:

1、生命存在周期:
A、理论上系统临时表是不需要显示的drop的,它是基于会话的,当系统临时表基于的连接关闭的时候,系统临时表将结束它的生命,这是最普通也是最常用的。

B、当一个被调用对象的返回值是一个在临时表上执行的结果集,这个被调用对象执行完毕的时候,是关闭连接的,但是,这时候临时表是不消失的,这时候系统临时表在调用者结束的时候才消失。因为返回的结果集只是一个相当于指针的东西,指向临时表内存中的地址,指向临时表的指针还在使用的时候,临时表是不能drop掉的。这带来了很复杂的问题,首先:存储过程中是不能drop临时表的,而程序中没有创建临时表,也应该是不drop的,临时表什么时间drop呢?其次:我们在一个连接中,无法2次调用一个存储过程,他将告诉你临时表已经存在。可以做一个简单的例子:写一个带有临时表返回结果的存储过程,在调用存储存储过程的程序中,我们完全可以访问这个临时表。
简单例子:
存储过程
/**
* JDBC 存储过程 ADMINISTRATOR.P1
*/
import java.sql.*;                   // JDBC 类

public class P1
{
    public static void p1 ( ResultSet[] rs ) throws SQLException, Exception
    {
        // 获取与数据库的连接
        Connection con = DriverManager.getConnection("jdbc:default:connection";
        PreparedStatement stmt = null;
        String sql;

        sql = "declare global temporary table session.temp(cc char(5)) not logged";
        stmt = con.prepareStatement( sql );
        stmt.executeUpdate();

        sql = "insert into  session.temp values ('1'),('2')";
        stmt = con.prepareStatement( sql );
        stmt.executeUpdate();
         
        sql = "SELECT * from session.temp";
        stmt = con.prepareStatement( sql );
        rs[0] = stmt.executeQuery();
        //关闭连接(注意,这个地方在rs[0]为临时表的结果集返回的时候,stmt是无法关闭的,临时表是无法drop的,而con是可以关闭的,关闭后临时表还存在)
        if (con != null) con.close();
    }
}                              

客户端调用我直接用命令行调用的。
db2 =>; connect to sample

   数据库连接信息

数据库服务器         = DB2/NT 7.2.1
SQL 授权标识         = ADMINIST...
本地数据库别名       = SAMPLE
//将自动提交设为false。
db2 =>; update command options using c off
DB20000I  UPDATE COMMAND OPTIONS 命令成功完成。

//调用过程
db2 =>; call p1()

CC
1
2

"P1" RETURN_STATUS:"0"
//看看存储过程中使用的临时表,数据是可以看到的。
db2 =>; select *  from session.temp

CC
-----
1
2

  2 条记录已选择。
//一个连接中再次调用,失败了
db2 =>; call p1()
SQL0601N  要创建的对象名与类型为"DECLARED TEMPORARY TABLE" 的现存名称 "SESSION.TEMP" 相同。  SQLSTATE=42710
//drop一下?ok,可以的
db2 =>; drop table session.temp
DB20000I  SQL 命令成功完成。
//看看还有吗?没了!
db2 =>; select *  from session.temp
SQL0204N  "SESSION.TEMP" 是未定义的名称。  SQLSTATE=42704
//再次调用,成功了
db2 =>; call p1()

CC
1
2

"P1" RETURN_STATUS:"0"


C、Websphere上的程序中使用系统临时表:因为websphere的连接使用连接池的技术,这带来了好处,但是同时也带来了一些让人容易误解的地方,我们在程序中要关闭连接,很多时候看上去是关闭了数据库的连接,事实上也是这样的,但是当websphere的连接数在websphere连接池规定的连接数的范围之内的时候,程序中关闭连接是不能直接关闭数据库的连接的,连接池使连接继续保持,这时候,我们的关闭连接释放的是该连接和相关因素在websphere和java程序中使用的资源,而该连接使用的数据库资源是无法得到释放的。也就是说,当我们在该连接上使用临时表的时候,我们在程序中关闭了连接,但是临时表是还存在的,连接池中把这个连接分配给其他程序使用的时候,其他程序还可以使用这个临时表,这并不是我们想要的。这要求我们在程序的中显式的drop掉临时表。(这是在南宁解决系统临时表使用问题中,碰到的一个问题,大家可以很容易的模拟出来)

同时这也让我们注意,一些设置,应该采取人为控制的方式,而不要采取默认,比如autoCommit,我们不能觉得程序结束了,就提交了,因为默认是程序结束提交的,如果错了就都回滚了,但是如果连接上设定的是autoCommit为true的话,程序出错就只能回滚你的出错前最后一次未提交事务,也许你还在为你程序中出现的这种错误头疼,他为什么前面的会提交呢?
一段代码,应尽可能的保持它的独立性,执行不要过多依赖于环境和其他的代码,我想这是应该考虑的。就象在oracle数据库上执行sql和在db2数据库上执行sql有很明显的区别一样,oracle默认是不提交的,而db2默认是提交的,这样在不主动控制事务的情况下,一个sql执行的结果是完全不同的。

2、数据存在周期
临时表的数据是在内存中的,当你向一个临时表插入数据的时候,他同时是直接的写到硬盘中的,如果你的缓冲池可以满足临时表的数据都存在内存中,它在使用的时候是不需要读硬盘上的数据的,除非你的缓冲池不能满足,这样会降低临时表的性能。我们知道,事务的提交和回滚是对数据库的更改做永久化,从内存中的更改到硬盘上的更改或者放弃更改(在更改实现的同时,是回收曾经占用的内存资源的)。对一个永久表,插入数据,就是在你提交之前,别的程序访问不了你插入的数据,在你提交之后,所有的程序都可以访问你插入的数据;而临时表不是这样的,无论执行提交还是回滚,临时表数据占用的内存资源都将被释放,同时临时表写到硬盘上的数据也全部删除。
也就是说,无论执行提交还是回滚,临时表的数据都没了,但是临时表还是存在的,这一点需要大家注意,在使用的过程中说插入了数据,但是没有数据,为什么呢??
看一个简单的命令行模拟的例子:
db2 =>; connect to sample

   数据库连接信息

数据库服务器         = DB2/NT 7.2.1
SQL 授权标识         = ADMINIST...
本地数据库别名       = SAMPLE
//创建临时表
db2 =>; declare global temporary table session.test(col1 char(5)) not logged
DB20000I  SQL 命令成功完成。
//插入数据
db2 =>; insert into session.test values('5')
DB20000I  SQL 命令成功完成。
//选择数据,没有数据?是的!
db2 =>; select * from session.test

COL1
-----

  0 条记录已选择。
//我们把提交方式改为默认不提交
db2 =>; update command options using c off
DB20000I  UPDATE COMMAND OPTIONS 命令成功完成。
//再次插入数据
db2 =>; insert into session.test values('5')
DB20000I  SQL 命令成功完成。
//选择数据,ok,我们看到数据了!
db2 =>; select * from session.test

COL1
-----
5

  1 条记录已选择。
//提交一下,或者执行rollback也可以   
db2 =>; commit
DB20000I  SQL 命令成功完成。
//数据没了
db2 =>; select * from session.test

COL1
-----

  0 条记录已选择。
   
   
以上是系统临时表使用的过程中我们程序开发者需要注意的可能出现的问题,知道问题是怎么出现的,我们应该如何解决出现的问题和如何更好的使用临时表,这是我们的目标。
论坛徽章:
5
ITPUB新首页上线纪念徽章
日期:2007-10-20 08:38:44生肖徽章2007版:鸡
日期:2008-01-02 17:35:53生肖徽章2007版:鼠
日期:2008-01-02 17:35:532009新春纪念徽章
日期:2009-01-04 14:52:282011新春纪念徽章
日期:2011-02-18 11:43:33
2#
发表于 2008-6-30 00:31 | 只看该作者

使用道具 举报

回复
论坛徽章:
3
授权会员
日期:2006-02-05 11:03:26数据库板块每日发贴之星
日期:2006-02-10 01:02:41IBM软件技术精英协会成员
日期:2006-12-21 15:37:12
3#
发表于 2008-7-11 18:37 | 只看该作者
感觉叫“用户临时表”比较合适。

使用道具 举报

回复
论坛徽章:
5
ITPUB新首页上线纪念徽章
日期:2007-10-20 08:38:44生肖徽章2007版:鸡
日期:2008-01-02 17:35:53生肖徽章2007版:鼠
日期:2008-01-02 17:35:532009新春纪念徽章
日期:2009-01-04 14:52:282011新春纪念徽章
日期:2011-02-18 11:43:33
4#
发表于 2008-7-13 09:37 | 只看该作者

回复 #3 ganquan 的帖子

晕哦 这个小"bug"你也发现了  不亏为高手啊

使用道具 举报

回复
论坛徽章:
68
林肯
日期:2013-09-12 15:57:33马自达
日期:2013-10-11 13:52:31路虎
日期:2014-01-26 14:35:49现代
日期:2013-08-29 14:39:50三菱
日期:2013-11-25 11:21:19雪佛兰
日期:2013-09-12 15:55:00一汽
日期:2013-11-28 14:15:05技术图书徽章
日期:2013-12-11 10:11:35技术图书徽章
日期:2013-12-11 10:10:51技术图书徽章
日期:2014-01-14 10:54:13
5#
发表于 2008-7-17 11:08 | 只看该作者
不错,此外建议在定义临时表时最好还是加入replace参数,防止出现“SQL0601N  要创建的对象名与类型为"DECLARED TEMPORARY TABLE" 的现存名称 "SESSION.TEMP" 相同。  SQLSTATE=42710”这个错误了;


另外,从系统编目表中如何查询那个session目前创建了那些系统临时表?
并且目前这些临时表是否还存在呢?

使用道具 举报

回复
论坛徽章:
2
设计板块每日发贴之星
日期:2009-01-16 01:01:08ITPUB9周年纪念徽章
日期:2010-10-08 09:28:51
6#
发表于 2008-7-24 17:18 | 只看该作者
是啊global这个词很误导人,我还以为和oracle的一样呢

使用道具 举报

回复
论坛徽章:
2
2010新春纪念徽章
日期:2010-03-01 11:20:00ITPUB十周年纪念徽章
日期:2011-11-01 16:24:51
7#
发表于 2010-1-26 15:25 | 只看该作者
commit 后临时表里边的数据没了,哈哈,这个以前没注意到

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 未成年人举报专区 
京ICP备16024965号-8  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表