循环SQL语句

时间:2018-10-25 14:08:43

标签: java sql

我的代码获取5,000行并进行了一些处理,然后停止。我想循环代码,以便在处理5,000行之后将获得另外5,000并再次处理。我希望它这样做直到没有更多的行了。

如果有人可以给我一个很棒的示例或伪代码,我将无法解决这个逻辑。

@Component("Inv226")
@Scope("prototype")
public class Inv226 extends BatchProgram {

    @Override
    public void process() {
        // Make it so the printing goes to the result page.
        this.webOn();
        print(" ", false);
        print("*****************************************", false);
        print("** B.INV226 Begins: " + getTime() + " " + date(YearFormat.YYYY), false);
        print("*****************************************", false);
        // Find the first 5,000 records to remove.

        //TODO find a way to keep looping
        // and obtaining another set of 5,000 records
        // when we're done processing each result set
        Calendar limitDate = Calendar.getInstance();
        limitDate.add(Calendar.DAY_OF_YEAR, -1095);
        MList<Inv> delList = new MList<>(Inv.class, //
                "CREATE_DATE < ? " //
                        + "order by CREATE_DATE " //
                        + "offset 0 rows " //
                        + "fetch next 5000 rows ONLY", //
                limitDate);
        // Set the commit limit.
        int commitLimit = 50;
        int i = 0;
        int delCount = 0;
        // Loop through them...
        for (Inv inv : delList) {
            // Remove each.
            inv.delete();
            if (++i >= commitLimit) {
                try {
                    this.commit();
                    print("Succesfully deleted " + i + " records");
                    delCount += i;
                    i = 0;
                    // Do we want a delay here?
                } catch (MccMidusException mme) {
                    // Is this a timestamp mismatch?
                    if ("0080".equals(mme.getErrorCode())) {
                        // Poke the record so the next invocation of Eddbl will process it correctly,
                        // along with the other 49 records in this block.
                        // Assuming the poke is successful, processing on the remaining Edb003 records in the
                        // block of 5000 will continue.
                        this.getIoHarness().pokeUow(mme.getUow());
                        // Call commit to get a new transaction started.
                        this.commit();
                        // Reset the counter.
                        i = 0;
                    } else {
                        throw mme;
                    }
                }
            }
        }
        delCount += i;
        // Ensure anything else gets committed.
        this.commit();
        print("*****************************************", false);
        print("** B.INV226 TOTAL DELETES OF GBL RECORDS OLDER THAN " + Calendar.DAY_OF_YEAR, -1095, false);
        print("** TOTAL RECORDS DELETED = " + delCount, false);
        print("** EDD003 Cleanup Ends : " + date(YearFormat.YYYY) + " " + getTime(), false);
        print("*****************************************", false);
        print(" ", false);

        this.webDone();
    }
}

编辑:我知道我可能需要在SQL语句本身附近的某个地方添加另一个循环

edit:我想避免重组工作或代码繁重的解决方案。我相信可以通过在我的SQL附近进行一个简单的循环来完成此操作,但无法弄清楚逻辑

3 个答案:

答案 0 :(得分:1)

Spring Batch提供了您正在寻找的chunk-oriented processing model。您可以使用面向块的步骤(块大小为5000)编写Spring Batch作业。

您可以在spring-batch-samples模块中找到许多有关如何编写此类作业的示例。

答案 1 :(得分:0)

好吧

从代码中快速判断,循环是删除行的地方,这意味着您一次加载5000行,并且可能需要重新运行脚本,直到没有剩余内容为止。

为什么不使用简单的SQL来检查数据库中剩余多少行,并有一个while语句来检查呢?

while(SELECT COUNT(*) FROM *tablename* > 0 ) {
   *your code*
}

即使您在while循环中删除了行,当再次进行检查时,数据库也会为COUNT()函数提供一个新值,这意味着它将进行检查,直到没有剩余的行为止。

答案 2 :(得分:0)

嗯,我最终解决了自己的问题。

这是代码段

 while (true) {
            MList<Fax> delList = new MList<>(Fax.class, //
                    "CREATE_DATE < ? " //
                            + "order by CREATE_DATE " //
                            + "offset 0 rows " //
                            + "fetch next 5000 rows ONLY", //
                    limitDate);
            if (delList.size() == 0) {
                break;
            }

这将连续执行代码,直到列表返回空白。感谢您的所有答复和想法。