Pemahaman saya tentang pertanyaan itu adalah bahwa Anda ingin menemukan ukuran ResultSet DI BYTES, bukan jumlah tuple ...
DejanLekic
Sangat menjengkelkan karena tidak memiliki dimensi yang tepat sebelum memproses data, tetapi jika Anda harus menyimpannya dalam larik, Anda dapat mempertimbangkan menggunakan struktur data seperti Daftar dan kemudian mengonversinya menjadi larik dengan metode toArray ().
AndreaTaroni86
Jawaban:
270
Lakukan SELECT COUNT(*) FROM ...kueri sebagai gantinya.
ATAU
int size =0;if(rs !=null){
rs.last();// moves cursor to the last row
size = rs.getRow();// get row id }
Dalam salah satu kasus, Anda tidak perlu mengulang seluruh data.
last () dan getRow () bukan metode statis di kelas ResultSet.
JeeBee
70
Demi singkatnya, saya selalu referensi metode dalam mode ini ketika menulis tentang mereka kepada orang lain, terlepas dari apakah mereka statis atau tidak. Sebenarnya membuat instance objek dan memanggil metode tersirat.
laz
51
Saya menulis SomeClass.staticMethod () dan SomeClass # instanceMethod () untuk mengurangi kebingungan.
Jake
9
Bagaimana cara mengambil nilai yang dikembalikan saat mengeksekusi select count?
Naftuli Kay
16
ResultSet#last()tidak bekerja pada semua jenis ResultSetobjek, Anda perlu memastikan bahwa Anda menggunakan salah satu dari keduanya ResultSet.TYPE_SCROLL_INSENSITIVEatauResultSet.TYPE_SCROLL_SENSITIVE
Marius Ion
91
ResultSet rs = ps.executeQuery();int rowcount =0;if(rs.last()){
rowcount = rs.getRow();
rs.beforeFirst();// not rs.first() because the rs.next() below will move on, missing the first element}while(rs.next()){// do your standard per row stuff}
Di dalam blok kode if (rs.last ()), bukankah metode yang benar adalah rs.beforeFirst () alih-alih rs.first ()? Dengan cara ini, Anda tidak melewatkan rekaman pertama di set hasil Anda untuk diproses di loop sementara.
karlgrz
jangan lupa untuk mengatur kursor kembali ke beforeFirst di luar blok if?
Goblin
Seperti yang dikatakan dokumen ResultSet , getRow()berfungsi untuk TYPE_FORWARD_ONLYResultSet, dan beforeFirst()melempar kesalahan untuk itu. Bukankah jawaban ini salah?
CodePro_NotYet
5
Ini hanya berfungsi ketika pernyataan dibuat dengan opsi gulir tidak sensitif:ps=conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
BullyWiiPlaza
19
Nah, jika Anda memiliki ResultSettipeResultSet.TYPE_FORWARD_ONLY Anda ingin tetap seperti itu (dan tidak beralih ke ResultSet.TYPE_SCROLL_INSENSITIVEatau ResultSet.TYPE_SCROLL_INSENSITIVEagar dapat digunakan .last()).
Saya sarankan hack yang sangat bagus dan efisien, di mana Anda menambahkan baris palsu / palsu pertama di bagian atas yang berisi jumlah baris.
Contoh
Katakanlah permintaan Anda adalah sebagai berikut
select MYBOOL,MYINT,MYCHAR,MYSMALLINT,MYVARCHAR
from MYTABLE
where...blahblah...
dan output Anda terlihat seperti
true65537"Hey"-32768"The quick brown fox"false123456"Sup"300"The lazy dog"false-123123"Yo"0"Go ahead and jump"false3"EVH"456"Might as well jump"...[1000 total rows]
Cukup refactor kode Anda ke sesuatu seperti ini:
Statement s=myConnection.createStatement(ResultSet.TYPE_FORWARD_ONLY,ResultSet.CONCUR_READ_ONLY);String from_where="FROM myTable WHERE ...blahblah... ";//h4xResultSet rs=s.executeQuery("select count(*)as RECORDCOUNT,"+"cast(null as boolean)as MYBOOL,"+"cast(null as int)as MYINT,"+"cast(null as char(1))as MYCHAR,"+"cast(null as smallint)as MYSMALLINT,"+"cast(null as varchar(1))as MYVARCHAR "+from_where
+"UNION ALL "//the "ALL" part prevents internal re-sorting to prevent duplicates (and we do not want that)+"select cast(null as int)as RECORDCOUNT,"+"MYBOOL,MYINT,MYCHAR,MYSMALLINT,MYVARCHAR "+from_where);
Output kueri Anda sekarang akan menjadi seperti
1000nullnullnullnullnullnulltrue65537"Hey"-32768"The quick brown fox"nullfalse123456"Sup"300"The lazy dog"nullfalse-123123"Yo"0"Go ahead and jump"nullfalse3"EVH"456"Might as well jump"...[1001 total rows]
Jadi kamu harus
if(rs.next())System.out.println("Recordcount: "+rs.getInt("RECORDCOUNT"));//hack: first record contains the record countwhile(rs.next())//do your stuff
Menarik, tetapi bagaimana Anda secara dinamis / umum menghasilkan pernyataan pilihan pertama: cast (null as boolean) sebagai MYBOOL, dll? Untuk itu Anda akan membutuhkan metadata dari kolom pernyataan "pilih" dan tipe data, seperti boolean, char, int, dll ...) yang mungkin memerlukan perjalanan DB ekstra yang akan meniadakan semua manfaat.
user1697575
Ini berguna ketika Anda memiliki akses ke semua detail bidang dan kecepatan adalah perhatian utama Anda (dan karena itu harus tetap berpegang teguh ResultSet.TYPE_FORWARD_ONLY)
Saya tidak mengerti apa kelemahan menggunakan metode ini untuk menghitung ukuran ResultSet. Ini hebat ... tidak menggunakan parameter SQL tambahan. Berikan komentar tentang metode ini.
Madeyedexter
5
Kinerja adalah kata kunci di sini. Bayangkan resultset Anda adalah 100 juta catatan maka Anda akan melihat masalahnya
Pierre
7
Saya ingin tahu ukuran hasil set SEBELUM memproses hasil karena saya perlu membuat array dengan ukuran yang sama sebelumnya. Dan, seperti disebutkan dalam jawaban lain, pemindaian semua baris dua kali tidak akan selalu berhasil.
Ivo
11
Saya mendapat pengecualian saat menggunakan rs.last()
Beralih dari ResultSet.TYPE_FORWARD_ONLYke ResultSet.TYPE_SCROLL_INSENSITIVEbiasanya menimbulkan dalam besar hukuman kinerja.
Unai Vivi
3
Saya memang mengujinya di meja saya (10 kolom, 187 392 baris). Pengujian saya melakukan kueri dan memuat semua elemen ke string. Untuk TYPE_FORWARD_ONLY butuh sekitar 1 detik. Untuk TYPE_SCROLL_INSENSITIVE butuh sekitar 7 detik. Ketika saya menggunakan agak SELECT COUNT(*) FROM default_tblsebelum SELECT COUNT(*) FROM default_tblbutuh waktu kurang dari 1,5 detik. Saya menguji pada database derby tertanam 10.11.1.1
Vit Bernatik
4
Cara mendapatkan ukuran ResultSet, Tidak perlu menggunakan ArrayList dll
int size =0;if(rs !=null){
rs.beforeFirst();
rs.last();
size = rs.getRow();}
Sekarang Anda akan mendapatkan ukuran, dan jika Anda ingin mencetak ResultSet, sebelum mencetak menggunakan baris kode berikut juga,
Banyak ppl di sini menyarankan ResultSet.last()tetapi untuk itu Anda perlu membuka koneksi karena ResultSet.TYPE_SCROLL_INSENSITIVEyang untuk database tertanam Derby hingga 10 kali lebih lambat daripada ResultSet.TYPE_FORWARD_ONLY.
Menurut tes mikro saya untuk database Derby dan H2 yang tertanam, secara signifikan lebih cepat untuk menelepon SELECT COUNT(*)sebelum SELECT Anda.
Ini adalah cara sederhana untuk melakukan rows-count.
ResultSet rs = job.getSearchedResult(stmt);int rsCount =0;//but notice that you'll only get correct ResultSet size after end of the while loopwhile(rs.next()){//do your other per row stuff
rsCount = rsCount +1;}//end while
Ya, itu berhasil. Tapi saya pikir OP berjuang dengan mengetahui jumlah baris sebelum benar-benar memprosesnya. Alasan kehidupan nyata saya harus berjuang dengan masalah ini sejauh ini: 1.) paging baris record 2.) menunjukkan baris diproses dalam tugas jangka panjang untuk keperluan pemantauan kemajuan ...
ppeterka
Preallocating ukuran struktur data adalah alasan lain. Saya telah melihat banyak lib mengembalikan 10 Daftar elemen ketika hanya ada satu nilai karena dev memiliki masalah yang sama dengan ResultSet.
Saya memeriksa nilai runtime dari antarmuka ResultSet dan menemukan itu adalah ResultSetImpl cukup banyak sepanjang waktu. ResultSetImpl memiliki metode yang disebutgetUpdateCount() yang mengembalikan nilai yang Anda cari.
Contoh kode ini harus cukup: ResultSet resultSet = executeQuery(sqlQuery); double rowCount = ((ResultSetImpl)resultSet).getUpdateCount()
Saya menyadari bahwa downcasting umumnya merupakan prosedur yang tidak aman tetapi metode ini belum mengecewakan saya.
Tidak bekerja dengan Tomcat / MySQL:java.lang.ClassCastException: org.apache.tomcat.dbcp.dbcp.DelegatingResultSet cannot be cast to com.mysql.jdbc.ResultSetImpl
Panu Haaramo
1
Hari ini, saya menggunakan logika ini mengapa saya tidak tahu menghitung RS.
int chkSize =0;if(rs.next()){do{..... blah blah
enter code here for each rs.
chkSize++;}while(rs.next());}else{
enter code here for rs size =0}// good luck to u.
theStatement=theConnection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);ResultSet theResult=theStatement.executeQuery(query);//Get the size of the data returned
theResult.last();int size = theResult.getRow()* theResult.getMetaData().getColumnCount();
theResult.beforeFirst();
Memindahkan kursor ke baris pertama di ResultSetobjek ini .
Pengembalian:
truejika kursor berada pada baris yang benar; falsejika tidak ada baris di set hasil
Melempar:
SQLException- jika terjadi kesalahan akses database; metode ini dipanggil pada himpunan hasil tertutup atau jenis himpunan hasil adalahTYPE_FORWARD_ONLY
Pendekatan termudah, Jalankan Hitung Count (*), lakukan resultSet.next () untuk menunjuk ke baris pertama dan kemudian lakukan resultSet.getString (1) untuk mendapatkan hitungan. Kode:
ResultSet rs = statement.executeQuery("Select Count(*) from your_db");if(rs.next()){int count = rs.getString(1).toInt()}
Jawaban:
Lakukan
SELECT COUNT(*) FROM ...
kueri sebagai gantinya.ATAU
Dalam salah satu kasus, Anda tidak perlu mengulang seluruh data.
sumber
select count
?ResultSet#last()
tidak bekerja pada semua jenisResultSet
objek, Anda perlu memastikan bahwa Anda menggunakan salah satu dari keduanyaResultSet.TYPE_SCROLL_INSENSITIVE
atauResultSet.TYPE_SCROLL_SENSITIVE
sumber
getRow()
berfungsi untukTYPE_FORWARD_ONLY
ResultSet, danbeforeFirst()
melempar kesalahan untuk itu. Bukankah jawaban ini salah?ps=conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
Nah, jika Anda memiliki
ResultSet
tipeResultSet.TYPE_FORWARD_ONLY
Anda ingin tetap seperti itu (dan tidak beralih keResultSet.TYPE_SCROLL_INSENSITIVE
atauResultSet.TYPE_SCROLL_INSENSITIVE
agar dapat digunakan.last()
).Saya sarankan hack yang sangat bagus dan efisien, di mana Anda menambahkan baris palsu / palsu pertama di bagian atas yang berisi jumlah baris.
Contoh
Katakanlah permintaan Anda adalah sebagai berikut
dan output Anda terlihat seperti
Cukup refactor kode Anda ke sesuatu seperti ini:
Output kueri Anda sekarang akan menjadi seperti
Jadi kamu harus
sumber
ResultSet.TYPE_FORWARD_ONLY
)sumber
Saya mendapat pengecualian saat menggunakan
rs.last()
:
itu karena secara default itu
ResultSet.TYPE_FORWARD_ONLY
, yang berarti Anda hanya dapat menggunakanrs.next()
solusinya adalah:
sumber
ResultSet.TYPE_FORWARD_ONLY
keResultSet.TYPE_SCROLL_INSENSITIVE
biasanya menimbulkan dalam besar hukuman kinerja.SELECT COUNT(*) FROM default_tbl
sebelumSELECT COUNT(*) FROM default_tbl
butuh waktu kurang dari 1,5 detik. Saya menguji pada database derby tertanam 10.11.1.1Cara mendapatkan ukuran ResultSet, Tidak perlu menggunakan ArrayList dll
Sekarang Anda akan mendapatkan ukuran, dan jika Anda ingin mencetak ResultSet, sebelum mencetak menggunakan baris kode berikut juga,
sumber
[Pertimbangan kecepatan]
Banyak ppl di sini menyarankan
ResultSet.last()
tetapi untuk itu Anda perlu membuka koneksi karenaResultSet.TYPE_SCROLL_INSENSITIVE
yang untuk database tertanam Derby hingga 10 kali lebih lambat daripadaResultSet.TYPE_FORWARD_ONLY
.Menurut tes mikro saya untuk database Derby dan H2 yang tertanam, secara signifikan lebih cepat untuk menelepon
SELECT COUNT(*)
sebelum SELECT Anda.Ini adalah lebih detail kode saya dan tolok ukur saya
sumber
Ini adalah cara sederhana untuk melakukan rows-count.
sumber
sumber
Saya memeriksa nilai runtime dari antarmuka ResultSet dan menemukan itu adalah ResultSetImpl cukup banyak sepanjang waktu. ResultSetImpl memiliki metode yang disebut
getUpdateCount()
yang mengembalikan nilai yang Anda cari.Contoh kode ini harus cukup:
ResultSet resultSet = executeQuery(sqlQuery);
double rowCount = ((ResultSetImpl)resultSet).getUpdateCount()
Saya menyadari bahwa downcasting umumnya merupakan prosedur yang tidak aman tetapi metode ini belum mengecewakan saya.
sumber
java.lang.ClassCastException: org.apache.tomcat.dbcp.dbcp.DelegatingResultSet cannot be cast to com.mysql.jdbc.ResultSetImpl
Hari ini, saya menggunakan logika ini mengapa saya tidak tahu menghitung RS.
sumber
sumber
Saya mengalami masalah yang sama. Menggunakan
ResultSet.first()
cara ini tepat setelah eksekusi menyelesaikannya:Dokumentasi ( tautan ):
sumber
Pendekatan termudah, Jalankan Hitung Count (*), lakukan resultSet.next () untuk menunjuk ke baris pertama dan kemudian lakukan resultSet.getString (1) untuk mendapatkan hitungan. Kode:
sumber
Beri nama pada kolom ..
Referensi kolom itu dari objek ResultSet ke int dan lakukan logika Anda dari sana ..
sumber