0

データベースに接続し、クエリを実行し、データベースからのデータを変数に割り当てるメソッドを含むクラスがあります。

この Java プログラムの目的は、クライアントのサーバーのセキュリティ脅威に関する情報を格納するデータベースをスキャンすることです。クエリが実行されると、攻撃の数 (target_stats.num_attacks) が 0 を超えていることが読み取られると、2 つのテーブル (target_stats と attack_stats) から選択されたデータ フィールドが返されます。

ターゲット テーブルからデータを正常に取得できますが、攻撃者のテーブルから null 値が取得され、データベース内のフィールドが null ではないことがわかっています。

私の質問: 好ましくない結果を引き起こしている私のクエリでエラー (おそらく論理エラー) を検出できる人はいますか? 私は初心者のプログラマーで、SQL にはかなり慣れていません。

また、私はこのプログラムでセッターとゲッターを学習中です。取得したデータはすべて別のクラスで使用する予定ですが、今のところターゲットフィールドだけでテストおよび学習しています。おそらくそれが問題を引き起こしていますか?

更新MySQLクエリブラウザでクエリを実行すると、同じ好ましくない結果が得られるため、問題はクエリロジックにあります。クエリと結合についていくつかの調査を行いましたが、まだ適切な知識が不足しているに違いありません。

私のコード(うまくいけば、フォーマットで正しく投稿してください):

public class Database {

String details = null;
int threat_level = 0;
ResultSet rslt = null;

private String target2;

Connection con;
public void createConnection() {

    //Establish a connection
    try {
        con = DriverManager.getConnection("sensitiveInformation");
    } catch (SQLException e) {

        e.printStackTrace();
    }
    System.out.println("Database connected");
}

public ResultSet getData() {

    String query =  "SELECT target_stats.server_id, target_stats.target, target_stats.threat_level, target_stats.client_id, attack_stats.attacker, attack_stats.num_this_attack " +
            "       FROM target_stats " +
            "       LEFT OUTER JOIN attack_stats " +
            "       ON target_stats.target = attack_stats.target " +
            "       WHERE target_stats.num_attacks > '0' " +
            "       AND target_stats.interval_id>'2'";
    Statement stmt = null;
    try {
        stmt = con.createStatement();
    } catch (SQLException e) {

        e.printStackTrace();
    }

    try {
        rslt = stmt.executeQuery(query);
    } catch (SQLException e) {

        e.printStackTrace();
    }

    return rslt;    

}

public void process() {

    try {


        String server_id = rslt.getString("server_id");
        target2 = rslt.getString("target");
        threat_level = rslt.getInt("threat_level");
        int client_id = rslt.getInt("client_id");
        String attacker = rslt.getString("attacker");
        String num_this_attack = rslt.getString("num_this_attack");
        details = "Target IP: " + target2 + " Server ID: " + server_id + " Client ID: " + client_id + " Threat Level: " + threat_level  + " Attacker IP: " + attacker + " Number of attacks: " + num_this_attack;


        System.out.println(details);


    } catch (SQLException e) {

        e.printStackTrace();
    }
}
public String getTraget2() {
    return target2;
}

}

更新: 各レコードを適切に読み取る別のクラスに while ループがあることに言及する必要があります。

更新 2: これがメイン クラスです。現在、GUI 要素には関心がありません。

public class MainDisplay extends JFrame {

static Toolkit tk = Toolkit.getDefaultToolkit();
static int Width = (int)tk.getScreenSize().getWidth();
static int Height = (int)tk.getScreenSize().getHeight();

public static JFrame frame = new JFrame();
public static JLayeredPane lpane = new JLayeredPane();
public static String target;

public static void main (String[] args) { new MainDisplay();

}

public MainDisplay() {

frame.setPreferredSize(new Dimension(Width, Height));
frame.setLocation(0,0);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setUndecorated(true);

//NoRisk Run = new NoRisk();
//Run.NoThreat();


ThreatPanel Run = new ThreatPanel();
Database Data = new Database();

//Create Connection to Database and run query

Data.createConnection();
Data.getData();
    try {
        while(Data.rslt.next()){
            Data.process();
            Run.TargetServer = Data.getTraget2();
            System.out.print(Data.getTraget2()); //for testing purposes
            Run.ShowThreats();
            try {
                Thread.sleep(1000*10); // sleeps for ten seconds
            } catch (InterruptedException e) {

                e.printStackTrace();
            }

        }
    } catch (SQLException e) {

        e.printStackTrace();
    }

//Run.ShowThreats();

frame.setLayout(new BorderLayout());
frame.add(lpane, BorderLayout.CENTER);
lpane.setBounds(0,0, Width, Height);






frame.pack();
frame.setVisible(true);

} }

4

3 に答える 3

1

データベースで同じクエリを実行しようとしましたか? あなたはそれがいくつかの結果を返すはずだと言いましたが、コードを入れる前にデータベースで試しましたか? データベースが望ましい結果を返さない場合は、クエリ ステートメントを調べます。たとえば、左外部結合の代わりに内部結合を使用する必要がある場合があります。

于 2013-06-28T06:18:36.513 に答える
1

攻撃者テーブルのフィールドは null ではない可能性がありますが、LEFT OUTER JOIN がある場合 - attack_stats テーブルに対応するデータがない場合、クエリに null 値が含まれます - それを確認してください。

クエリは問題ないように見えます - LEFT INNER JOINを試してみてください。そうすると、attack_stats テーブルに対応するデータがない行が表示されなくなります。

于 2013-06-28T06:45:46.603 に答える
0

パット、このコードを呼び出している場所から、メイン メソッドを投稿できますか。また、結果セットを反復してカーソルを移動する必要があります。

while(rslt.next())
{
 String server_id = rslt.getString("server_id");
        target2 = rslt.getString("target");
        threat_level = rslt.getInt("threat_level");
        int client_id = rslt.getInt("client_id");
        String attacker = rslt.getString("attacker");
        String num_this_attack = rslt.getString("num_this_attack");
        details = "Target IP: " + target2 + " Server ID: " + server_id + " Client ID: " + client_id + " Threat Level: " + threat_level  + " Attacker IP: " + attacker + " Number of attacks: " + num_this_attack;


        System.out.println(details);

}
于 2013-06-28T06:21:42.787 に答える