让我先解释一下场景,假设我们有一些用于销售目的的交易表。并且可以根据用户在特定销售应用程序上的操作来插入或更新数据。由于数据可用于财务目的,财务部门希望拥有已创建或更新至中午12点的数据。但我们不能停止这个项目。所以,数据也可以在中午12点之后更新。
现在,我有一个复杂的select语句。它会产生大量的数据。
现在,当我们生成数据并开始将其导出到CSV时,需要花费大量时间。半个多小时。
所以,我的问题是在导出过程中,如果用户正在使用应用程序,因此数据正在更新,这是否也会影响生成数据的导出功能?导出过程中是否可以更改生成的数据?因为SQL首先只生成可见的数据,然后根据分页的变化加载另一个数据。
如果是,如何控制这种行为?
2条答案
按热度按时间nvbavucw1#
不,数据不会改变。当你在Oracle中运行一个查询时,它会为你提供当时的数据。
即使您的查询运行了几个小时,并且其他会话更改了数据并提交了这些更改,您的查询也不会注意到这些更改。Oracle将使用其内部更改历史记录,以确保您获得的数据是您开始查询的时间戳。
yduiuuwa2#
只要你的“分页”是一个只执行一次的SQL语句,然后逐步地获取,oracle就会构造一致的读(CR)缓冲区,方法是对SQL启动后发生的任何更改应用撤消(它在块ITL中找到大于它自己的事务开始SCN的SCN,然后读取undo并应用undo记录来重建块在事务开始时的外观(SCN),这样您就可以得到与表100%空闲时相同的结果。这是一个很好的东西(尽管在某些情况下会导致一些严重的性能问题),也是Oracle的一个重要特性。
然而,如果你的“分页”是一个 * 系列 * 的SQL语句(使用
WHERE
子句以编程方式构造来完成分页),无论出于何种原因,那么每个语句都是CR保证一致的,但它们之间不是。如果您使用的是这种方法,而其他人正在更新表,那么您将得到不一致的数据。因此,请确保您的提取是单个原子执行。在一个exec之后多次 fetches 是可以的,但多次 * exec * 则不行。