SQLの列数対応について

このQ&Aのポイント
  • SQLの列数対応について質問があります。Apache+servletで開発しています。動的なSQL文から抽出される列数に対応するためにVectorクラス(Bean)を作成しましたが、実行できない問題が発生しています。
  • 現在、開発中のシステムで動的なSQL文の列数に対応するためにVectorクラス(Bean)を作成しました。しかし、実行時にエラーが発生しています。どこが問題なのか教えてください。
  • SQLの列数対応のために作成したVectorクラス(Bean)に関して質問です。現在、実行時にエラーが発生しており、正しく動作していません。問題の原因を教えてください。
回答を見る
  • ベストアンサー

SQLの列数対応

Apache+servletで開発しています。 SQL文から抽出される列数に動的に対応するため 以下のようなVectorクラス(Bean)を作成しました。 ResultSet rset = stmt.executeQuery(sql_s); ResultSetMetaData rsmd = rset.getMetaData(); int cnt = rsmd.getColumnCount(); rset.next(); for (int i=1;i<=cnt;i++) {  String colName = rsmd.getColumnName(i);  String colValue = rset.getString(i);  ht.put(colName, colValue); } list.addElement(ht); SQL実行結果は一件であるためwhile等の処理はしていません。 ht は Hashtableで、list はVectorです。 列名を一つずつ指定していけば問題なくできたのですが、 (例: ht.put("列名", rset.getString("列名")); 列数が多い場合に面倒。かつ動的なSQLに対応できない。 ため上記に変えたところ、コンパイルは通りますが実行できません。 tryでひっかかって何もブラウザに返しません。 どこが駄目なのでしょうか?

  • ssm3u
  • お礼率70% (42/60)
  • Java
  • 回答数1
  • ありがとう数1

質問者が選んだベストアンサー

  • ベストアンサー
  • rancer
  • ベストアンサー率66% (6/9)
回答No.1

Hashtableって、NULL値を受け付けないはず・・・ NULL対策する必要があるのでは?

ssm3u
質問者

お礼

put のところですね^^ありがとうございます。 APIに書いてありましたが、「ふぅ~ん」程度で読み飛ばしてました。 if (colValue != null){  ht.put(colName, colValue); } これで無事ブラウザに表示されました。 本当は colName にもNULL対策が必要なのですが・・・ これで良いとします。 ありがとうございました。

関連するQ&A

  • マルチスレッドプログラムからのファイル出力

    VM:java1.4.2 OS:WindowsXp マルチスレッドのプログラムで、一つのファイルにテキストの出力を行うところで、うまくいかないところがあります。 <ソースファイル> import java.io.*; import java.util.*; import java.text.*; public class ThreadIppai { public static void main(String[] args) { for (int i = 0; i < 100; i++) { Thread thread = new ThreadHontai(); thread.start(); } } } class ThreadHontai extends Thread { public void run() { try { for (int i = 0; i < 500; i++) { BufferedWriter bw = new BufferedWriter(new FileWriter( "D:\\out.log", true)); String msg = (String) Values.ht.get(String.valueOf((int) (Math.random() * 10)).substring(0, 1)) + "\n"; bw.write(msg, 0, msg.length()); bw.flush(); bw.close(); } } catch (Exception e) { e.printStackTrace(); } } } class Values { public static Hashtable ht = new Hashtable(); static { // ht.put("0", "0000000000"); // ht.put("1", "1111111111"); // ht.put("2", "2222222222"); // ht.put("3", "3333333333"); // ht.put("4", "4444444444"); // ht.put("5", "5555555555"); // ht.put("6", "6666666666"); // ht.put("7", "7777777777"); // ht.put("8", "8888888888"); // ht.put("9", "9999999999"); ht.put("0", "0"); ht.put("1", "11"); ht.put("2", "222"); ht.put("3", "3333"); ht.put("4", "44444"); ht.put("5", "555555"); ht.put("6", "6666666"); ht.put("7", "77777777"); ht.put("8", "888888888"); ht.put("9", "9999999999"); } } <問題点> ファイルに出力された結果をみると、テキストの一部が欠けていたり、改行がされない行があったりします。 おそらく、同期処理を加えてないからだとは思うのですが・・・。(質問に続く) <質問1> テキストの一部が欠けたり、改行されない行が発生する原因はなぜでしょうか? たとえば、「0」と「11」を出力するとき、同時に複数のスレッドが書き込んだ場合、「101」となるのは、なんとなく分かります。 しかし、これが「01」のように、出力されるべき文字が出力されないという現象が発生してます。 <質問2> htにputする値の文字列長が、すべて異なっていますが、これをコメントアウトされている行のように、すべて同じ文字列長に した場合、上記の問題は発生しなくなります。 この原因はなんでしょうか? <質問3> この問題を、ThreadHontaiクラスのfor文の中だけの変更で解決することは可能でしょうか?(極力手を加えずに) synchronizedブロックの追加でいけるのかと思いましたが、試行錯誤の結果うまくいきませんでした。 以上、よろしくお願いします。

  • SQL文のSELECTで読み、配列に取り込み

    SQL文のSELECTで読み、配列に取り込みたく、下記のプログラム作成しましたがエラー『ExecuteReader: Connection プロパティは初期化されていません。』が出て困っています。 どこで、どのように設定すればよいのでしょうか? Private Function Sosiki_kouzou() As String()() Dim Sosiki_tbl2(3)() As String Dim Dread As Data.OleDb.OleDbDataReader Dim Com As New Data.OleDb.OleDbCommand Com = New Data.OleDb.OleDbCommand("SELECT ORG_ID,SHORT_OU_JA, PARENT_ORG_ID FROM meldandy.WF_ORGANIZATION") Dread = Com.ExecuteReader Dim Cnt1 As Integer Cnt1 = 0 Do While (Dread.Read()) Cnt1 = Cnt1 + 1 Sosiki_tbl2(1)(Cnt1) = Dread.GetString(1) Sosiki_tbl2(2)(Cnt1) = Dread.GetString(2) Sosiki_tbl2(3)(Cnt1) = Dread.GetString(3) Loop Return Sosiki_tbl2 End Function VisualStadioを始めたばかりの素人です。 的外れかも知れませんがよろしくお願いいたします。

  • while文の表示

    こんにちは 今DB接続し DBからデータを表示するのを勉強しています public String[][] selectExec(String sql) throws SQLException{ Statement smt = con.createStatement(); //ステートメントオブジェクト作成 SQL文を送るために作成 ResultSet aa=smt.executeQuery(sql); //SQLから要素取得 ArrayList<String> TESTNO = new ArrayList<String>(); //TESTNO用ののArrayList作成 ArrayList<String> NAME = new ArrayList<String>(); //KAME用 ArrayList<String> KANA = new ArrayList<String>(); //KANA用 while(aa.next()){ //Resultsetが最終行になるまで実行 TESTNO.add(aa.getString("TESTNO")); NAME.add(aa.getString("NAME")); KANA.add(aa.getString("KANA")); } aa.close(); //使い終わったリザルトクローズ smt.close(); //ステートメントクローズ      //オブジェクトの解放 return hairetu(TESTNO,NAME,KANA); public String[][] selectExec(String sql, int fromIdx,int toIdx) throws SQLException{ String[][]all=selectExec(sql); ArrayList list = new ArrayList(Arrays.asList(all[0])); ArrayList list1 = new ArrayList(Arrays.asList(all[1])); ArrayList list2 = new ArrayList(Arrays.asList(all[2])); int i=1; while(i<fromIdx){ //指定された前のリスト削除 list.remove(0); list1.remove(0); list2.remove(0); i++; } while(toIdx<list .size()){ //指定されたあとのリスト削除 list .remove(toIdx); list1.remove(toIdx); list2.remove(toIdx); toIdx++; } return hairetu(list ,list1,list2); public String[][] hairetu(ArrayList T,List N ,List K){ String[][]all=new String[3][T.size()]; all[0] = (String[])T.toArray(new String[0]);//配列TSETNOに収納 all[1] = (String[])N.toArray(new String[0]);//配列NAMEに収納 all[2] = (String[])K.toArray(new String[0]);//配列KANAに収納 return all; selectExec(String sql)で全表示 selectExec(String sql, int fromIdx,int toIdx) で列を何行~何行を指定 でリストに変換、リスト削除して 二次元配列にもどしているのですが たとえば 1~5を指定すると 0 0 0 1 1 1 2 2 2 3 3 3 4 4 4 6 6 6 8 8 8 ↑のように 5ひとつとばしで表示されます while文の書き方がわるいのでしょうか・・・・ アドバイスお願いします

    • ベストアンサー
    • Java
  • データ取得後、JTABLE列幅を変更できませんか

    データベースからデータを取得して(ResultSetMetaData)、Jtableに表示したのですが、列幅を項目ごとに変更したいのですが、できるのでしょうか? 項目ヘッダーはできたのですが。。。 ResultSetMetaData rm = rs.getMetaData(); int cnum = rm.getColumnCount(); colname = new ArrayList<String>(cnum); //列名の取得 String[] hder = {"月日","区分","コード","商品"}; for(int i=1; i<=cnum; i++){ colname.add(hder[i-1]); } //行の取得 data = new ArrayList<ArrayList>(); while(rs.next()){ ArrayList<String> rowdata = new ArrayList<String>(); for(int i=1; i<=cnum; i++){ if (rs.getObject(i)==null){ rowdata.add("");} else{ rowdata.add(rs.getObject(i).toString());} } data.add(rowdata); } 表示はできるのですが、各項目ごとに列幅が、しようとMaxsizeとかsetPreferredWidth などを行ってもうまくでいきません。

  • メソッドの分割(リファクタリング?)

    指導教官からプログラム自体には問題はないが長すぎるのでメソッドを分割したほうがよいといわれました。以下に書きます(一部改変) try{ System.out.println("1. 2. どちらかを選択してください"); InputStreamReader reader = new InputStreamReader(System.in); BufferedReader br = new BufferedReader(reader); String str = br.readLine(); int res = Integer.parseInt(str); if(!str.matches("[1-2]+")){ System.out.println("1、2から選択してください。"); continue;} if(res == 1){ System.out.println("キーワードを入力"); reader = new InputStreamReader(System.in); br = new BufferedReader(reader); str = br.readLine(); String sql = "SQL文"; ResultSet result = stmt.executeQuery(sql); //vectorにデータを格納 Vector vector1 = new Vector(); String[] array1 = new String[2]; while(result.next()){ array1[0] = result.getString("Res1"); array1[1] = result.getString("Res2"); vector1.addElement(array1); array1 = new String[2];} for(int i = 0;i < vector1.size();i++ ){ String Res1 = null;  String Res2 = null; String[] str1 = (String[])vector1.get(i); Res1 = str1[0]; Res2 = str1[1]; System.out.println("Res1,Res2は" + Res1 + "\t" + Res2);}} if(res == 2){1と同様なので省略・・}} catch(IOException e){ System.out.println(e + "例外が発生しました");} }} メソッドの分割のコツはあるのでしょうか?お勧めの本はございますか? 長くてすいません。

    • ベストアンサー
    • Java
  • JavaでDBを作りたい

    一応自分で出来る限りコードは書いたのですが、上手くいきません。 実行すると一応テーブルは表示されるのですが、更新や削除をしようとすると「java.sql.SQLException: executeQuery メソッドを更新用に使用することはできません」などというエラーが出てしまいます。 また、検索機能をつけるとすればどのようにすればいいでしょうか? (文字数の関係上import文など一部割愛しています) public class test extends BaseFrame implements MouseListener { static int KETU; private JLabel l_code, l_title, l_price; private JTextField tf_code, tf_title, tf_price; private String s_code, s_title, s_price; private JButton b_add, b_cha, b_del; private JTable tb; private JScrollPane sp; private JPanel pn; // パネル分割 private ResultSet rs = null; public static void main(String[] args) { new test("データの挿入"); } public test(String title) { super(title); Container cp = getContentPane(); // テーブル表示エリアの設定(省略)// tb = new JTable(new DefaultTableModel()); // テーブル初期は空の状態 sqlTable("select * from USERS"); // 起動と同時にテーブルを表示 } public void mouseClicked(MouseEvent evt) { Object src = evt.getSource(); s_code = tf_code.getText(); s_title = tf_title.getText(); s_price = tf_price.getText(); if (src == b_add) { sqlTable("insert into USERS values(" + (KETU + 1) + ",'" + s_title+ "'," + s_price + ")"); sqlTable("select * from USERS"); } else if (src == b_cha) { sqlTable("update USERS set title= '" + s_title + "', price= " + s_price + " WHERE code= " + s_code); sqlTable("select * from USERS"); } else if (src == b_del) { sqlTable("delete from USERS where code= " + s_code); sqlTable("select * from USERS"); } tf_code.setText(""); tf_title.setText(""); tf_price.setText(""); } public void mouseEntered(MouseEvent evt) { Object src = evt.getSource(); if (src == b_add) { tf_code.setBackground(Color.black); } else if (src == b_cha) { } else if (src == b_del) { tf_title.setBackground(Color.black); tf_price.setBackground(Color.black); } } public void mouseExited(MouseEvent evt) { Object src = evt.getSource(); if (src == b_add) { tf_code.setBackground(Color.white); } else if (src == b_cha) { } else if (src == b_del) { tf_title.setBackground(Color.white); tf_price.setBackground(Color.white); } } @Override public void mousePressed(MouseEvent evt) { } public void mouseReleased(MouseEvent evt) { } public void sqlTable(String sql) { // SQLテーブル表示用 System.out.println(sql); try { String drv = "org.apache.derby.jdbc.ClientDriver"; String url = "jdbc:derby://localhost:1527/jad2011"; Class.forName(drv); Connection cn = DriverManager.getConnection(url); Statement st = cn.createStatement(); rs = st.executeQuery(sql); //SQLの実行 ResultSet rs = st.executeQuery(sql); tb.setModel(new MyTableModel(rs)); rs.close(); st.close(); cn.close(); } catch (Exception e) { e.printStackTrace(); } } // テーブルモデルクラス class MyTableModel extends AbstractTableModel { private Vector<Object> colname; private Vector<Object> data; public MyTableModel(ResultSet rs) { try { // 列数の取得 ResultSetMetaData rm = rs.getMetaData(); int cnum = rm.getColumnCount(); colname = new Vector<Object>(cnum); // 列名の取得 for (int i = 1; i <= cnum; i++) { colname.addElement(rm.getColumnName(i)); } data = new Vector<Object>(); KETU = 0; while (rs.next()) { Vector<Object> rowdata = new Vector<Object>(); for (int i = 1; i <= cnum; i++) { rowdata.addElement(rs.getObject(i)); if (i == 1) { if (KETU < ((Integer) rs.getObject(i))) { KETU = ((Integer) rs.getObject(i)); } } } data.addElement(rowdata); } } catch (Exception e) { e.printStackTrace(); } } public int getRowCount() { return data.size(); } public int getColumnCount() { return colname.size(); } public Object getValueAt(int row, int column) { Vector rowdata = (Vector) data.elementAt(row); return rowdata.elementAt(column); } public String getColumnName(int column) { return (String) colname.elementAt(column); } }

    • ベストアンサー
    • Java
  • javaのResultSetについて

    javaのResultSetについてですが、getStringでSQL名を選択して取得するのですが、変数で指定した場合は、文字列と判断され取得できないのでしょうか? 例えばSQLの列名の「test」を取得したい場合は、「rs.getString(test)」と記述しますが、 以下のように変数に置き換えて、取得しようすると、 String test2 = "test"; rs.getString(test2)というようにすると、カラムがありませんとエラーが返ってきます。 変数に置き換えて実行したいのですが、何か良い方法がないかご教授いただけますでしょうか。 宜しくお願い致します。

    • ベストアンサー
    • Java
  • 2つのリストのマージ方法について

    2つのリストのマージ方法について 下記の要件を満たしたいと考えています。 ・リスト1・2をkeyをキーにマージしたい。  リスト1[0]:key=2, value1=b  リスト1[1]:key=3, value1=d  リスト1[2]:key=4, value1=e  ・  ・  ・  リスト2[0]:key=1, value2=A  リスト2[1]:key=2, value2=B  リスト2[2]:key=5, value2=F  リスト2[3]:key=6, value2=G  ・  ・  ・  ↓  リスト3[0]:key=1, value1=A, value=""  リスト3[1]:key=2, value1=b, value=B  リスト3[2]:key=3, value1=d, value=""  リスト3[3]:key=4, value1=e, value=""  リスト3[4]:key=5, value1="", value=F  リスト3[5]:key=6, value1="", value=G  ・  ・  ・ ・リスト1・2はkeyの昇順でソート済。各リスト内では重複しているkeyはない。 ・マージ後もkeyの昇順にしたい。 ・実際のリストはそれぞれ数万件~数十万件なので、パフォーマンスを考慮したい。 下記のように作成してみたのですが、無理やりやりました感があり、分かりづらくバグがありそうです。またループでnewもしてたりしてパフォーマンスも悪そうです。もっとスマートにパフォーマンスもよい方法がないでしょうか? int checkedCount = 0; for (int i = 0; i < list1.size(); i++) { String str1 = list1.get(i).get("key"); for (int j = checkedCount; j < list2.size(); j++) { Map<String, String> map3 = new HashMap<String, String>(); String str2 = list2.get(j).get("key"); if (str1.compareTo(str2) < 0) { if (i != list1.size() - 1) { map3.put("key", str1); map3.put("value1", list1.get(i).get("value1")); map3.put("value2", ""); list3.add(map3); break; } else { Map<String, String> map4 = new HashMap<String, String>(); map4.put("key", str2); map4.put("value1", ""); map4.put("value2", list2.get(j).get("value2")); list3.add(map4); } } else if (str1.compareTo(str2) == 0) { map3.put("key", str1); map3.put("value1", list1.get(i).get("value1")); map3.put("value2", list2.get(j).get("value2")); list3.add(map3); checkedCount = j + 1; break; } else { map3.put("key", str2); map3.put("value1", ""); map3.put("value2", list2.get(j).get("value2")); list3.add(map3); checkedCount = j + 1; } } }

    • ベストアンサー
    • Java
  • Vectorと配列

    お世話になります。 GUIから3つのString文字列を受け取り、追加ボタンを押した時点でVector(List)に格納し、登録ボタンを押してはじめてDBにデータを格納させたいのですが、 Vector list = new Vector(); String addData[] = {txta.getText(), txtb.getText(), txtc.getText()}; for(int i=0; i<addData.length; i++){ list.addElement(addData[i]); } しかし、連続してデータを追加するとlistには {data1,data2,data3,data4,data5,data6} のように入ってしまいます。 これを {data1,data2,data3} {data4,data5,data6} のようにlistに格納するにはどうすればいいでしょうか? ご教授頂ければ幸いです。 よろしくお願いします。

    • ベストアンサー
    • Java
  • Mapの扱いについて

    いつもお世話になっております。 ただ今Java1.3にてMapを使用したプログラムを作成しております。 String[] hoge = {"0","0","0","0"}; String[] key = {"いいい","ううう","えええ"}; int[] point = {0,1,3}; String[] value = {"5","8","2"}; Map map = new HashMap(); map.put("あああ",hoge); map.put("いいい",hoge); map.put("ううう",hoge); map.put("えええ",hoge); map.put("おおお",hoge); for (int i=0; i < key.length; i++) { String[] wk_hoge = (String)map.get(key[i]); wk_hoge[point[i]] = value[i]; map.put(key[i],wk_hoge); } 上記のように記述し、結果としては あああ="0","0","0","0" いいい="5","0","0","0" ううう="0","8","0","0" えええ="0","0","0","2" おおお="0","0","0","0" としたいのですが、実際の結果が あああ="5","8","0","2" いいい="5","8","0","2" ううう="5","8","0","2" えええ="5","8","0","2" おおお="5","8","0","2" となってしまいます。 なぜそのようになってしまうのか原因がわかりません。 どなたかアドバイスをお願い致します。

    • ベストアンサー
    • Java

専門家に質問してみよう