it-swarm.com.de

Wie kann ich mit ResultSet eine Zeilenanzahl in Java erhalten?

Ich versuche, eine einfache Methode zu erstellen, die ein ResultSet als Parameter empfängt und ein int zurückgibt, das die Zeilenanzahl des ResultSet enthält. Ist dies eine gültige Methode oder nicht so viel?

int size = 0;
    try {
        while(rs.next()){
            size++;
        }
    }
    catch(Exception ex) {
        System.out.println("------------------Tablerize.getRowCount-----------------");
        System.out.println("Cannot get resultSet row count: " + ex);
        System.out.println("--------------------------------------------------------");
    }

Ich habe das versucht:

int size = 0;
try {
    resultSet.last();
    size = resultSet.getRow();
    resultSet.beforeFirst();
}
catch(Exception ex) {
    return 0;
}
return size;

Ich habe jedoch eine Fehlermeldung erhalten, die com.Microsoft.sqlserver.jdbc.SQLServerException: The requested operation is not supported on forward only result sets. sagt

Vielen Dank im Voraus für die Hinweise!

59
Tiwaz89

Wenn Sie Zugriff auf die vorbereitete Anweisung haben, die zu dieser Ergebnismenge führt, können Sie verwenden

connection.prepareStatement(sql, 
  ResultSet.TYPE_SCROLL_INSENSITIVE, 
  ResultSet.CONCUR_READ_ONLY);

Dadurch wird Ihre Anweisung so vorbereitet, dass Sie den Cursor zurückspulen können. Dies ist auch im ResultSet Javadoc dokumentiert.

Im Allgemeinen können das Weiterleiten und Zurückspulen von Cursorn jedoch für große Ergebnismengen ziemlich ineffizient sein. Eine andere Option in SQL Server wäre, die Gesamtzahl der Zeilen direkt in Ihrer SQL-Anweisung zu berechnen:

SELECT my_table.*, count(*) over () total_rows
FROM my_table
WHERE ...
54
Lukas Eder

ihre SQL-Anweisung zum Erstellen von Code kann wie sein 

statement = connection.createStatement();

So lösen Sie "com.Microsoft.sqlserver.jdbc.SQLServerException: Die angeforderte Operation wird nicht unterstützt, wenn nur Forward-Resultsets weitergeleitet werden" 

statement = connection.createStatement(
    ResultSet.TYPE_SCROLL_INSENSITIVE, 
    ResultSet.CONCUR_READ_ONLY);

Nach obiger Änderung können Sie verwenden

int size = 0;
try {
    resultSet.last();
    size = resultSet.getRow();
    resultSet.beforeFirst();
}
catch(Exception ex) {
    return 0;
}
return size;

reihenzählung erhalten

31
Fathah Rehman P
Statement s = cd.createStatement();
ResultSet r = s.executeQuery("SELECT COUNT(*) AS rowcount FROM FieldMaster");
r.next();
int count = r.getInt("rowcount");
r.close();
System.out.println("MyTable has " + count + " row(s).");

Manchmal unterstützt JDBC die folgende Methode nicht. Diese Lösung wird von Fehler wie "TYPE_FORWARD_ONLY" verwendet

Sqlite wird in JDBC nicht unterstützt.

resultSet.last();
size = resultSet.getRow();
resultSet.beforeFirst();

Verwenden Sie zu diesem Zeitpunkt diese Lösung.

Vielen Dank..

22
Java Man

Führen Sie stattdessen eine SELECT COUNT(*) FROM ...-Abfrage aus.

Ich habe gerade eine Gettermethode gemacht.

public int getNumberRows(){
    try{
       statement = connection.creatStatement();
       resultset = statement.executeQuery("your query here");
       if(resultset.last()){
          return resultset.getRow();
       } else {
           return 0; //just cus I like to always do some kinda else statement.
       }
    } catch (Exception e){
       System.out.println("Error getting row count");
       e.printStackTrace();
    }
    return 0;
}
5
The01Guy

Wenn Sie eine Tabelle haben und die ID als primäres und automatisches Inkrement speichern, funktioniert dies 

Beispielcode zum Abrufen der gesamten Zeilenanzahl http://www.Java2s.com/Tutorial/Java/0340__Database/GettheNumberofRowsinaDatabaseTable.htm

Unten ist der Code

import Java.sql.Connection;
import Java.sql.DriverManager;
import Java.sql.ResultSet;
import Java.sql.ResultSetMetaData;
import Java.sql.Statement;

public class Main {
  public static void main(String[] args) throws Exception {
    Connection conn = getConnection();
    Statement st = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
        ResultSet.CONCUR_UPDATABLE);

    st.executeUpdate("create table survey (id int,name varchar(30));");
    st.executeUpdate("insert into survey (id,name ) values (1,'nameValue')");
    st.executeUpdate("insert into survey (id,name ) values (2,null)");
    st.executeUpdate("insert into survey (id,name ) values (3,'Tom')");
    st = conn.createStatement();
    ResultSet rs = st.executeQuery("SELECT * FROM survey");

    rs = st.executeQuery("SELECT COUNT(*) FROM survey");
    // get the number of rows from the result set
    rs.next();
    int rowCount = rs.getInt(1);
    System.out.println(rowCount);

    rs.close();
    st.close();
    conn.close();

  }

  private static Connection getConnection() throws Exception {
    Class.forName("org.hsqldb.jdbcDriver");
    String url = "jdbc:hsqldb:mem:data/tutorial";

    return DriverManager.getConnection(url, "sa", "");
  }
}
3
anand

Andere haben bereits geantwortet, wie Sie Ihr Problem lösen können. Ich werde also nicht wiederholen, was bereits gesagt wurde. Ich sage jedoch Folgendes: Sie sollten wahrscheinlich einen Weg finden, um Ihre Probleme zu lösen, ohne die Ergebnismenge zu kennen, bevor Sie das Programm lesen Ergebnisse. 

Es gibt sehr wenige Umstände, unter denen die Zeilenanzahl vor dem Lesen der Ergebnismenge tatsächlich benötigt wird, insbesondere in einer Sprache wie Java. Ich denke nur an die Stelle, an der eine Zeilenzahl erforderlich wäre, wenn die Zeilenzahl die einzigen Daten ist, die Sie benötigen (in diesem Fall wäre eine Zählabfrage überlegen). Andernfalls ist es besser, ein Wrapper-Objekt zur Darstellung Ihrer Tabellendaten zu verwenden und diese Objekte in einem dynamischen Container wie einer ArrayList zu speichern. Sobald die Ergebnismenge iteriert wurde, können Sie die Anzahl der Arraylisten ermitteln. Bei jeder Lösung, bei der die Anzahl der Zeilen vor dem Lesen der Ergebnismenge bekannt ist, können Sie sich wahrscheinlich eine Lösung vorstellen, bei der die Anzahl der Zeilen vor dem Lesen ohne großen Aufwand bekannt ist. Wenn Sie an Lösungen denken, die die Zeilenzahl vor der Verarbeitung nicht kennen müssen, speichern Sie das ResultSet-Problem beim Scrollen bis zum Ende der Ergebnismenge und dann zurück zum Anfang (was für große Ergebnismengen sehr teuer sein kann). . 

Ich sage natürlich nicht, dass es nie Situationen gibt, in denen Sie die Zeilenanzahl benötigen, bevor Sie eine Ergebnismenge lesen. Ich sage nur, dass in den meisten Fällen, wenn die Leute denken, sie müssten die Ergebnismenge vor dem Lesen zählen, dies wahrscheinlich nicht der Fall ist, und es lohnt sich 5 Minuten, darüber nachzudenken, ob es einen anderen Weg gibt.

Wollte nur meine 2 Cent zum Thema anbieten.

2
aeskreis

Ihre Funktion gibt die Größe eines ResultSets zurück, der Cursor wird jedoch nach dem letzten Datensatz gesetzt. Wenn Sie ihn also nicht durch Aufruf von beforeFirst (), first () oder previous () zurückspulen, können Sie seine Zeilen nicht lesen und zurückspulen Methoden funktionieren nicht mit forward nur ResultSet (Sie erhalten die gleiche Ausnahme, die Sie in Ihrem zweiten Codefragment erhalten).

2
socha23

Die meisten Treiber unterstützen nur das Resultset "Vorwärts" - daher werden Methoden wie "Letzte", "BeforeFirst" usw. nicht unterstützt.

Der erste Ansatz ist geeignet, wenn Sie die Daten auch in derselben Schleife erhalten - ansonsten wurde das resultSet bereits iteriert und kann nicht mehr verwendet werden.

In den meisten Fällen besteht die Anforderung darin, die Anzahl der Zeilen zu ermitteln, die eine Abfrage zurückgeben würde, ohne die Zeilen abzurufen. Das Durchlaufen der Ergebnismenge zum Ermitteln der Zeilenanzahl ist fast identisch mit der Verarbeitung der Daten. Es ist besser, stattdessen eine andere count (*) - Abfrage auszuführen. 

2
gkamal

Das ResultSet verfügt über Methoden, die den Cursor je nach Option vor und zurück bewegen. Standardmäßig wird es vorwärts verschoben (Typ der Ergebnismenge TYPE_FORWARD_ONLY). Wenn CONSTANTS nicht die korrekte Bildlauffähigkeit und Aktualisierung des Ergebnissatzes angibt, wird möglicherweise eine Fehlermeldung angezeigt. beforeLast () Diese Methode hat keine Auswirkung, wenn die Ergebnismenge keine Zeilen enthält Fehler, wenn sie nicht TYPE_FORWARD_ONLY ist.

Der beste Weg, um zu prüfen, ob leere Zeilen abgerufen wurden --- Nur um einen neuen Datensatz einzufügen, nachdem die Nicht-Existenz geprüft wurde

if( rs.next() ){

   Do nothing
} else {
  No records fetched!
}

Siehe hier

1
Yergalem

Hier ist ein Code, der das Abrufen der Anzahl zur Instanziierung eines Arrays vermeidet, jedoch stattdessen eine ArrayList verwendet und die ArrayList unmittelbar vor der Rückgabe in den erforderlichen Array-Typ konvertiert.

Beachten Sie, dass die Supervisor-Klasse hier die ISupervisor-Schnittstelle implementiert. In Java können Sie jedoch keine Umwandlung von object [] (die einfache toArray () -Methode der ArrayList-Methode) in ISupervisor [] durchführen (so wie Sie es in C # tun können) müssen alle Listenelemente durchlaufen und das Ergebnis-Array auffüllen.

/**
 * Get Supervisors for given program id
 * @param connection
 * @param programId
 * @return ISupervisor[]
 * @throws SQLException
 */
public static ISupervisor[] getSupervisors(Connection connection, String programId)
  throws SQLException
{
  ArrayList supervisors = new ArrayList();

  PreparedStatement statement = connection.prepareStatement(SQL.GET_SUPERVISORS);
  try {
    statement.setString(SQL.GET_SUPERVISORS_PARAM_PROGRAMID, programId);
    ResultSet resultSet = statement.executeQuery();  

    if (resultSet != null) {
      while (resultSet.next()) {
        Supervisor s = new Supervisor();
        s.setId(resultSet.getInt(SQL.GET_SUPERVISORS_RESULT_ID));
        s.setFirstName(resultSet.getString(SQL.GET_SUPERVISORS_RESULT_FIRSTNAME));
        s.setLastName(resultSet.getString(SQL.GET_SUPERVISORS_RESULT_LASTNAME));
        s.setAssignmentCount(resultSet.getInt(SQL.GET_SUPERVISORS_RESULT_ASSIGNMENT_COUNT));
        s.setAssignment2Count(resultSet.getInt(SQL.GET_SUPERVISORS_RESULT_ASSIGNMENT2_COUNT));
        supervisors.add(s);
      }
      resultSet.close();
    }
  } finally {
    statement.close();
  }

  int count = supervisors.size();
  ISupervisor[] result = new ISupervisor[count];
  for (int i=0; i<count; i++)
    result[i] = (ISupervisor)supervisors.get(i);
  return result;
}
0
George Birbilis

Folgende zwei Optionen haben sich für mich bewährt:

1) Eine Funktion, die die Anzahl der Zeilen in Ihrem ResultSet zurückgibt.

private int resultSetCount(ResultSet resultSet) throws SQLException{
    try{
        int i = 0;
        while (resultSet.next()) {
            i++;
        }
        return i;
    } catch (Exception e){
       System.out.println("Error getting row count");
       e.printStackTrace();
    }
    return 0;
}

2) Erstellen Sie eine zweite SQL-Anweisung mit der Option COUNT.

0
Nico