查找时间戳和标识不按顺序排列的行的有效方法是什么?

发布于 2024-08-20 07:39:02 字数 1361 浏览 5 评论 0原文

背景

我有一个 MS SQL 应用程序,它每小时从我们的 Oracle 计费数据库中读取一次数据,寻找新的付款。它通过存储基于每次运行时找到的最新时间戳的 CRT_DTTM 的时间戳来实现此目的。

例如

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

问题:

我想知道是否有一种方法可以检查已插入表中的行以查找这些行身份与时间戳无序的口袋:

数据库序列与时间戳

我想找到这种情况下的数据包,以了解 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() 运行它

Background:

I have a MS SQL application that reads data from our Oracle billing database once an hour, looking for new payments. It does this by storing a timestamp based on the CRT_DTTM of the most recent timestamp found each time it runs.

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')

After this result is returned, the MAX(CRT_DTTM) is stored as the starting timestamp for the next hourly run.

What appears to be happening is that sometimes there's a transaction running on the Oracle side that is inserting data into the table at the same time I'm running my query. The rows are seemingly not being inserted in order of the timestamp they got. This means that my MAX(CRT_DTTM) is greater than some of the rows that get inserted after my query completes. I've missed payment information, and my systems are out of balance.

I believe that I can work around this by simply modifying my SQL statement above to add:

...
AND CRT_DTTM < SYSDATE - INTERVAL '10' MINUTE

The Question:

What I want to know is if there's a way to examine the rows already inserted into the table to find those pockets where the identity is out of order with the timestamp:

database sequence vs timestamp

I want to find the pockets of data with this situation to know if 10 minutes is long enough to hold off on looking at the timestamp.

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

Or perhaps I'm overlooking some basic transaction isolation level setting? I'm running this via a linked server with OPENQUERY()

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

じее 2024-08-27 07:39:02
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
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
舞袖。长 2024-08-27 07:39:02

“这些行似乎没有按照它们获得的时间戳顺序插入。”
更有可能的是,它们没有按时间戳顺序提交,因此它们已被插入,但在您运行查询时尚未提交。

查看 Oracle DBA 是否会为您提供 V$TRANSACTION 的资助。然后,您可以查看任何未结交易的开始时间、未结交易的时长等。
此外,如果 Oracle 数据库是 RAC,则序列号(最接近 Oracle 标识列)也很可能不按顺序排列。 RAC 中的每个节点都有自己的缓存以减少争用。

在 11gR2 中,他们引入了 WAITING_ON_PENDING_DML< /a> 来适应这种情况。

"The rows are seemingly not being inserted in order of the timestamp they got. "
More likely they are not being COMMITED in timestamp order, so they have been inserted but not committed when you run your query.

See if the Oracle DBA will give you grants on V$TRANSACTION. You can then see the start time of any open transactions, how long they are open, etc.
Also if the Oracle database is RAC, it is very likely that the sequence numbers (the closest Oracle has to identity columns) are not in order either. Each node in the RAC has its own cache to reduce contention.

In 11gR2, they've introduced a WAITING_ON_PENDING_DML to cater for this situation.

怪异←思 2024-08-27 07:39:02
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;

如果我误解了您的问题,请让我知道我错过了什么。

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

EDIT:

I wrote this answer, then realized it was more or less the same query you already have. So I must not understand your question.

My query will "...examine the rows already inserted into the table to find those pockets where the identity is out of order with the timestamp" which I thought was your question.

BTW, if you're just looking for what's the biggest jump backwards of a timestamp, you can use:

select max(t2.timestamp - t1.timestamp)
from table t1
join table t2 on t1.id = t2.id - 1;

If I'm misunderstanding your question, please let me know what I'm missing.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文