有没有不使用嵌套while循环来实现这个程序的不同方法? [复制]

Posted

技术标签:

【中文标题】有没有不使用嵌套while循环来实现这个程序的不同方法? [复制]【英文标题】:Is there a different way of implementing this program without using nested while loop? [duplicate] 【发布时间】:2019-01-26 09:16:49 【问题描述】:

目前我的程序运行正常,但是我如何在不使用嵌套 while 循环(一个 while 循环在另一个 while 循环中)的情况下实现这个程序。这是一种儿童编程方式,我的办公室同事不想让我写像这样的代码。那么有没有不同的方法来实现这个程序或实现上面代码中看到的while循环的正确方法?

这是我当前的代码:

package Snomed.Snomed;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Date;

import catalog.Root;

public class Snomedinfo 
    public void snomedinfoinsert() 
        Root oRoot = null;
        ResultSet oRsSelect = null;
        PreparedStatement oPrStmt = null;
        PreparedStatement oPrStmt2 = null;
        PreparedStatement oPrStmtSelect = null;
        String strSql = null;

        String snomedcode = null;
        ResultSet oRs = null;
        String refid = null;
        String id = null;
        String effectivetime = null;
        String active = null;
        String moduleid = null;
        String conceptid = null;
        String languagecode = null;
        String typeid = null;
        String term = null;
        String caseSignificanceid = null;

        try 
            oRoot = Root.createDbConnection(null);
            strSql = "SELECT  id FROM snomed_conceptdata WHERE active=1 ";
            oPrStmt2 = oRoot.con.prepareStatement(strSql);
            oRsSelect = oPrStmt2.executeQuery();
            String strSql2 = "SELECT  * FROM snomed_descriptiondata WHERE conceptid =? AND active=1  ";
            oPrStmtSelect = oRoot.con.prepareStatement(strSql2);
            String sql = "INSERT INTO snomedinfo_data (refid,id,effectivetime,active,moduleid,conceptid,languagecode,typeid,term,caseSignificanceid) VALUES( ?, ?, ?,?,?,?,?,?,?,?)";
            oPrStmt = oRoot.con.prepareStatement(sql);
            while (oRsSelect.next()) //first while loop
            
                snomedcode = Root.TrimString(oRsSelect.getString("id"));

                oPrStmtSelect.setString(1, snomedcode);

                oRs = oPrStmtSelect.executeQuery();

                while (oRs.next()) //second while loop
                
                    refid = Root.TrimString(oRs.getString("refid"));
                    id = Root.TrimString(oRs.getString("id"));
                    effectivetime = Root.TrimString(oRs.getString("effectivetime"));
                    active = Root.TrimString(oRs.getString("active"));
                    moduleid = Root.TrimString(oRs.getString("moduleid"));
                    conceptid = Root.TrimString(oRs.getString("conceptid"));
                    languagecode = Root.TrimString(oRs.getString("languagecode"));
                    typeid = Root.TrimString(oRs.getString("typeid"));
                    term = Root.TrimString(oRs.getString("term"));
                    caseSignificanceid = Root.TrimString(oRs.getString("caseSignificanceid"));


                    oPrStmt.setString(1, refid);
                    oPrStmt.setString(2, id);
                    oPrStmt.setString(3, effectivetime);
                    oPrStmt.setString(4, active);
                    oPrStmt.setString(5, moduleid);
                    oPrStmt.setString(6, conceptid);
                    oPrStmt.setString(7, languagecode);
                    oPrStmt.setString(8, typeid);
                    oPrStmt.setString(9, term);
                    oPrStmt.setString(10, caseSignificanceid);
                    oPrStmt.executeUpdate();
                


            

            System.out.println("done");
         catch (Exception e) 
            e.printStackTrace();

         finally 

            oRsSelect = Root.EcwCloseResultSet(oRsSelect);
            oRs = Root.EcwCloseResultSet(oRs);
            oPrStmt = Root.EcwClosePreparedStatement(oPrStmt);
            oPrStmt = Root.EcwClosePreparedStatement(oPrStmt2);
            oPrStmt = Root.EcwClosePreparedStatement(oPrStmtSelect);
            oRoot = Root.closeDbConnection(null, oRoot);
        
    

    public static void main(String args[]) throws Exception 

        Snomedinfo a = new Snomedinfo();
        a.snomedinfoinsert();

    



注意:导入过程也可以正常工作,但速度有点慢。我已经尝试为 conceptid 列使用索引。

【问题讨论】:

这种问题最好在Code Review问 请不要一遍又一遍地问同一个问题,但有细微的差别。它只会让你获得更多的反对票和重复关闭投票,并最终被禁止提问。 @IlmariKaronen 完成 【参考方案1】:

如果我正确阅读了您的代码,那么您是从一个表中读取并添加到另一个表中,并且从不使用应用程序中的数据。如果是这种情况,那么最好的情况是编写一个 db 过程来转换您的数据并从您的应用程序中执行它。

【讨论】:

【参考方案2】:

如果我是正确的,您正在使用两个查询从数据库中获取数据。 使用这个嵌套查询,它将节省数据库连接工作和嵌套while循环

SELECT * FROM snomed_descriptiondata WHERE conceptid in (SELECT id FROM snomed_conceptdata WHERE active=1) AND active=1

【讨论】:

我希望查询是分开的!!不想使用单个查询或任何类型的连接!! 加上 snomed_descriptiondata 和 snomed_conceptdata 这两个表都有超过 1300000 行数据,所以会很慢!! 首先从 snomed_conceptdata 表中获取数据并存储在列表中。那么如果您熟悉多线程,请使用 Executor 框架,其中工作线程将从 snomed_descriptiondata 表中读取数据记录并插入到其他表中。【参考方案3】:

由于INSERT 语句中使用的所有数据都来自您的“SELECT”语句,因此在您的 java 应用程序和数据库之间进行额外的往返是没有意义的。在一条 SQL 语句中执行所有内容将为您提供最佳性能。

你的SQL语句应该是这样的

INSERT INTO snomedinfo_data (refid,id,effectivetime,active,moduleid,conceptid,languagecode,typeid,term,caseSignificanceid)
SELECT d.refid, d.id, d.effectivetime, d.active, d.moduleid, d.conceptid, d.languagecode, d.typeid, d.term, d.caseSignificanceid
FROM snomed_descriptiondata d
JOIN snomed_conceptdata c ON c.id = d.conceptid AND c.active = 1 AND d.active = 1

你的java代码可以归结为这个

try 
    oRoot = Root.createDbConnection(null);
    String sql = "INSERT INTO snomedinfo_data...";
    oPrStmt = oRoot.con.prepareStatement(sql);
    oPrStmt.executeUpdate();

【讨论】:

我希望查询是分开的!!不想使用单个查询或任何类型的连接!! 加上 snomed_descriptiondata 和 snomed_conceptdata 这两个表都有超过 1300000 行数据,所以会很慢!! 不,一条插入语句不可能比你现在的慢。相反,它应该快得多,当你有这么多行时,没有什么比数据库更快的了。不想使用单个查询或连接是没有意义的。 所以如果不使用单个查询或连接就没有办法避免嵌套的while循环?? @davidmathew 不是我能看到的。

以上是关于有没有不使用嵌套while循环来实现这个程序的不同方法? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

在嵌套的 while 循环中继续

在一个函数中以两个不同的while循环输入不起作用

使用没有嵌套 while 循环的滑动窗口删除注释

循环嵌套

Redshift 中的嵌套 While 循环

自学Python入门 (for和while)循环嵌套及用法