背景
我有一个MS SQL应用程序,每小时从我们的Oracle计费数据库中读取数据,寻找新的付款。它通过存储基于每次运行时找到的最新时间戳的CRT_DTTM
的时间戳来实现此目的。
e.g。
SELECT *
FROM V_TRANS
WHERE TRANS_CLS = 'P'
AND CRT_DTTM > TO_DATE('2010-01-25 12:59:44', 'YYYY-MM-DD HH24-MI-SS')
返回此结果后,MAX(CRT_DTTM)
将存储为下一小时运行的起始时间戳。
似乎正在发生的事情是,有时在Oracle端运行的事务是在我运行查询的同时将数据插入表中。这些行似乎没有按照它们获得的时间戳顺序插入。这意味着我的MAX(CRT_DTTM)
大于我的查询完成后插入的一些行。我错过了付款信息,而且我的系统不平衡。
我相信我可以通过简单地修改上面的SQL语句来解决这个问题:
...
AND CRT_DTTM < SYSDATE - INTERVAL '10' MINUTE
问题:
我想知道的是,是否有办法检查已经插入到表中的行,以找到那些带有时间戳的身份无序的口袋:
database sequence vs timestamp http://i46.tinypic.com/r70sk0.png
我希望在这种情况下找到大量数据,以便了解10分钟是否足够长,以便暂时停止查看时间戳。
SELECT *
FROM V_TRANS t1
JOIN V_TRANS t2
ON t1.trans_id < t2.trans_id
AND t2.crt_dttm < t1.crt_dttm
WHERE t1.TRANS_CLS = 'P'
AND t1.CRT_DTTM > TO_DATE('2010-01-25 12:59:44', 'YYYY-MM-DD HH24-MI-SS')
-- Only look at an interval of one day
AND t1.CRT_DTTM < TO_DATE('2010-01-25 12:59:44', 'YYYY-MM-DD HH24-MI-SS') + 1
或许我忽略了一些基本的事务隔离级别设置?我是通过OPENQUERY()
答案 0 :(得分:2)
SELECT
*
FROM (
SELECT
t1.*,
RANK() OVER (ORDER BY trans_id) AS trans_id_rank,
-- Ordering by trans_id after CRT_DTTM to cater for transactions within the same second
RANK() OVER (ORDER BY CRT_DTTM, trans_id) AS CRT_DTTM_rank
FROM V_TRANS t1) t
WHERE trans_id_rank <> CRT_DTTM_rank
答案 1 :(得分:1)
“这些行似乎没有按照他们获得的时间戳的顺序插入。” 更有可能的是,它们没有按时间戳顺序进行COMMITED,因此在运行查询时它们已被插入但未提交。
查看Oracle DBA是否会为您提供V $ TRANSACTION的授权。然后,您可以查看任何未结交易的开始时间,交易时间等。 此外,如果Oracle数据库是RAC,则很可能序列号(最接近的Oracle必须标识列)也不是有序的。 RAC中的每个节点都有自己的缓存来减少争用。
在11gR2中,他们引入了WAITING_ON_PENDING_DML来满足这种情况。
答案 2 :(得分:0)
select t1.id, t2.id, t1.timestamp - t2.timestamp
from table t1
join table t2 on t1.id = t2.id - 1
where t1.timestamp < t2.timestamp
编辑:
我写了这个答案,然后意识到它或多或少是你已经拥有的相同查询。所以我不能理解你的问题。
我的查询将“...检查已经插入到表格中的行,以找到那些带有时间戳的身份无序的口袋”,我认为这是你的问题。
顺便说一句,如果您只是想查找时间戳最大的跳跃,您可以使用:select max(t2.timestamp - t1.timestamp)
from table t1
join table t2 on t1.id = t2.id - 1;
如果我误解了你的问题,请让我知道我错过了什么。