DELPHI盒子
!实时搜索: 盒子论坛 | 注册用户 | 修改信息 | 退出
检举帖 | 全文检索 | 关闭广告 | 捐赠
技术论坛
 用户名
 密  码
自动登陆(30天有效)
忘了密码
≡技术区≡
DELPHI技术
lazarus/fpc/Free Pascal
移动应用开发
Web应用开发
数据库专区
报表专区
网络通讯
开源项目
论坛精华贴
≡发布区≡
发布代码
发布控件
文档资料
经典工具
≡事务区≡
网站意见
盒子之家
招聘应聘
信息交换
论坛信息
最新加入: maxding
今日帖子: 36
在线用户: 8
导航: 论坛 -> DELPHI技术 斑竹:liumazi,sephil  
作者:
男 sxqwhxq (步惊云) ★☆☆☆☆ -
普通会员
2024/5/13 9:04:46
标题:
讨论一个临时表数据更新问题 浏览:741
加入我的收藏
楼主: 讨论一个临时表数据更新问题。
用select *into # temptb from tbtest创建临时表。
然后
fdquery.open('select * from #temptb ');
现对fdquery进行增删改,然后post,临时表#temptb数据更新了,请问
怎么把临时表数据更新到数据库表tbtest呢?
----------------------------------------------
-
作者:
男 guth (落叶) ★☆☆☆☆ -
普通会员
2024/5/13 13:01:10
1楼: 临时表和原表就是两个独立的表,删除原表的旧数据,insert into select语句就可以。要不你就update联表修改。
----------------------------------------------
-
作者:
男 sxqwhxq (步惊云) ★☆☆☆☆ -
普通会员
2024/5/13 13:54:54
2楼: 感觉删除原表数据再提交有点危险
我想到一个办法,也许可以使用rtc的数据集测控器,将临时表连接的数据集的数据变化转化为update sql语句,提交服务器执行呢
----------------------------------------------
-
作者:
男 hectic (村雨Hectic) ▲▲▲▲▲ -
普通会员
2024/5/13 14:06:04
3楼: 你用临时表可能是为了确保数据完整原子性,也就是必须所有该修改的数据全都修改完之后才能投入使用,你可以用事务来解决,如果修改不完整就回滚,修改完整就直接一次性commit
----------------------------------------------
-
作者:
男 sxqwhxq (步惊云) ★☆☆☆☆ -
普通会员
2024/5/13 14:18:34
4楼: 使用临时表,我觉得有很大作用。
局部临时表只在当前会话可见,这样保持不会被别的连接所修改。
例如你的程序有100个单位使用,各个单位的表都是一样的
这样你查询、修改就得为每个sql语句加上where dwmc='单位一'
如果你想使用动态视图,这个问题可以解决,但还是不太好用
如果你在程序启动时就建临时表,这些临时表都加上where子句,现在你再增删改查就不要再写where子句,如果你的程序有1000条sql,这样避免了很多错误,是不是很爽?
这种临时表、临时数据集模拟的就是类似动态视图的功能。
----------------------------------------------
-
作者:
男 wk_knife (wk_knife) ★☆☆☆☆ -
盒子活跃会员
2024/5/13 16:30:46
5楼: 查询不返回记录的主键么?通常修改、删除都是基于主键做操作的吧。为啥还要带查询时的条件?
----------------------------------------------
-
作者:
男 sxqwhxq (步惊云) ★☆☆☆☆ -
普通会员
2024/5/19 10:19:25
6楼: 用临时表代替视图,在开发项目实践中有重要意义。
例如假设软件有100个用户,系统有100个表,其中代码性质的公共表有30个,另外有60个业务表,这60个表都必须有一个表示使用单位的字段dwName。
这样你在开发程序时,不可能为每个单位的每个表建100个视图,这样你无法在delphi编写代码。这样你在程序中,不得不为每个sql语句都要加上使用'where dwName='+quotedstr(GdwName);这样的子句,很容易出错。
如果能够在程序启动时就创建'select * into #tempB1 from tbB1 where dwName='+quotedstr(GdwName)临时表,然后你所有的查询更新语句select * from #tempb1,都不必添加这个where子句了。省去了很多工作量,也保证了逻辑正确。
现在问题是如何更新临时表?使用数据集监视器,将临时表的增删改语句转化为update sql,则问题就全部解决了。
----------------------------------------------
-
作者:
男 zhyhero (zhyhero) ★☆☆☆☆ -
盒子活跃会员
2024/5/19 15:56:04
7楼: 内存表和临时表应该不是一个意思。
----------------------------------------------
z@S7
作者:
男 hectic (村雨Hectic) ▲▲▲▲▲ -
普通会员
2024/5/19 23:45:35
8楼:

update tbB1 
set A.字段1=B.字段1, A.字段2=B.字段2, A,字段3=B.字段3 
from #tempB1 B, tbB1 A 
where A.dwName=B.dwName


这样?

这个dwName必须是双方表的唯一索引字段,否则更新后的结果会出问题。
----------------------------------------------
-
作者:
男 sxqwhxq (步惊云) ★☆☆☆☆ -
普通会员
2024/5/20 10:02:30
9楼: 数据更新使用数据监控组件自动生成sql语句提交就可以了。
现在的问题是,如果某种原因断线了,服务器生成的生成的临时表却不会删除,必须得为每个临时表建个list,如果对应的连接断线了,需要相应删除
----------------------------------------------
-
作者:
男 luckyrandom (luckyrandom) ★☆☆☆☆ -
普通会员
2024/5/20 12:49:48
10楼: 个人理解连接断线了,服务器端会自动清理临时表
至于SQL Server是这个机制。。MySQL/PG/Oracle大概率也是这个机制
----------------------------------------------
SQL SERVER DBA QQ:315054403 曾经的Delphier  缘在上海
作者:
男 sxqwhxq (步惊云) ★☆☆☆☆ -
普通会员
2024/5/20 13:56:16
11楼: 可是,我删除在服务器建立的数据库连接对象fdconnection后,原来用fdconnection.execsql(select * into #tbtemp from tbMain')建立的临时表却仍然留在内存中,因为我重新连接时,报告该内存表已经存在,这是什么原因呢?有一种可能是使用了连接池,但关闭连接池后问题依旧。
使用局部临时表还有一个问题,用数据集监视器获取客户端内存表数据更改的sql后,数据变化产生的sql语句会提交数据库实体表,但局部临时表内容却并不会提交,还得需要重建该内存表以获取最新数据
从上面这两点看,权衡一下工作量,发现想用局部临时表取代delphi中的where子句代价不小。
----------------------------------------------
-
作者:
男 wk_knife (wk_knife) ★☆☆☆☆ -
盒子活跃会员
2024/5/20 17:19:34
12楼: 不行就钻研下分区表呗,以用户单位为分区条件。既然传统的写法不如你意,可以挑战下分区表。
----------------------------------------------
-
作者:
男 hectic (村雨Hectic) ▲▲▲▲▲ -
普通会员
2024/5/21 0:41:24
13楼: sqlserver临时表有两种
#table 一个#号是当前会话临时表,当前会话退出以后临时表会自当删除。
##table 两个#号是全局临时表,所有连接的会话都能看到,所有会话断开以后,临时表才会删除。
----------------------------------------------
-
作者:
男 sxqwhxq (步惊云) ★☆☆☆☆ -
普通会员
2024/5/21 15:41:19
14楼: 我理解firedac的数据库连接组件FDConnection就是一个连接会话管理器,FDConnection.connected:=true表示开启一个连接会话,此时数据集组件fdquery可以增删除改查;FDConnection.connected:=false表示关闭一个连接会话,此时与之关联的内存临时表应该会释放。但奇怪是关闭连接,甚至释放连接对象,关闭数据库连接池,这些临时表却并没有删除,因为我重新连接时,提示这些临时表已经存在。
----------------------------------------------
-
作者:
男 pcplayer (pcplayer) ★☆☆☆☆ -
普通会员
2024/5/21 16:54:17
15楼: 数据库的连接,实际上是客户端和服务器端建立了一个 TCP 连接。

当然,FDConnection 可能是调用具体的数据库自己提供的客户端的库,而不是自己去建立连接。比如使用 FireBird,调用的是 FbClient.dll;

至于 FDConnection.Close,那也许它自己内部有一些 pool 的机制,你关闭了连接,但它内部并没有真正关闭,而是 pool 了。

当然,也可能你使用的数据库本身,对临时表的管理的机制,也许客户端断开连接它不清除?

临时表如果数据来不是很多,不如直接在 Delphi 程序里面自己使用内存表来实现,比在数据库里面搞,我个人觉得还更简单一些。比如使用 FdMemTable。
----------------------------------------------
-
作者:
男 sxqwhxq (步惊云) ★☆☆☆☆ -
普通会员
2024/5/21 17:15:57
16楼: 临时表如果数据来不是很多,不如直接在 Delphi 程序里面自己使用内存表来实现,比在数据库里面搞,我个人觉得还更简单一些。比如使用 FdMemTable。
----------
本地内存表肯定方便、成熟。但它是一个delphi对象。
而select * into # tb from tbMain where 是一个数据库对象,它建立在服务器,用途不一样,我可以select form #tb,这样加个#比写where dwName=这样的子句更方便
----------------------------------------------
-
作者:
男 hectic (村雨Hectic) ▲▲▲▲▲ -
普通会员
2024/5/21 17:37:24
17楼: 如果关闭连接后会话临时表依然存在,大概率是连接池设计导致的。
----------------------------------------------
-
作者:
男 sxqwhxq (步惊云) ★☆☆☆☆ -
普通会员
2024/5/21 17:53:12
18楼: 对不起,是我犯的低级错误,上面的断开连接后局部临时表不删除的问题不存在。
我把select * into #tb写成了select * into tb,导致建立了实体表tb。
但用局部临时表代替视图的方案仍然有一个很大的缺陷:
局部临时表只是实体表数据的一个复制集,表的主键、外键和相关约束并不会随同复制,这是一个很难处理的问题。
----------------------------------------------
-
作者:
男 sxqwhxq (步惊云) ★☆☆☆☆ -
普通会员
2024/5/22 10:49:03
19楼: 用局部临时表替代动态视图有很多不好处理的问题,还是老老实实写where吧
----------------------------------------------
-
作者:
男 wk_knife (wk_knife) ★☆☆☆☆ -
盒子活跃会员
2024/5/23 9:30:43
20楼: 啥是动态视图啊?
----------------------------------------------
-
信息
登陆以后才能回复
Copyright © 2CCC.Com 盒子论坛 v3.0.1 版权所有 页面执行117.1875毫秒 RSS