Hatena::ブログ(Diary)

on the center line.

2008-12-03

MySQLでNULLを含むカラムにINDEXを張っても大丈夫

| 16:39

「NULLを含むカラムにINDEXを張っても使用されないので、できればNULLを意味するデフォルト値を設定しよう」という記述を何回かみたことがあって、てっきりそうだと思い込んでいました。が、MySQLマニュアルには、

column_name IS NULL  を使用した検索では、column_name  にインデックスが
張られている場合にインデックスが使用されます。
http://dev.mysql.com/doc/refman/4.1/ja/mysql-indexes.html 

と書いてありました。たぶん「NULLが含まれていると駄目な場合もある」のだと思いますが、上記のようなケース(IS NULLの比較)では問題ないようです。

自分で調べてみるものです。

2008-06-25

MySQLで大きなデータを登録しようとするとcom.mysql.jdbc.PacketTooBigException: 発生

| 15:26

MySQLで、3M程度のデータを登録しようとすると、以下のような例外が発生。

com.mysql.jdbc.PacketTooBigException: Packet for query is too large (3526504 > 1048576). 
You can change this value on the server by setting the max_allowed_packet' variable.
	at com.mysql.jdbc.MysqlIO.send(MysqlIO.java:3068)
	at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1834)
	at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:1976)
	at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2503)
	at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1737)
	at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2022)
	at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1940)
	at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1925)

エラーメッセージが言っているように、「max_allowed_packet」を変更すれば直りました。すなわち、my.cnf(Windows の場合は my.ini)に、以下の記述を追加して完了。

[mysqld]         ←←← [mysql]でないことに注意!
max_allowed_packet = 16M

MySQLのマニュアルページはこちら

それにしても親切なエラーメッセージです。僕も見習わなくては。

2008-03-11

PL/SQLでジェネリックなリストを使う

| 11:55

PL/SQLにはTable型というものがあり、これは簡単にいうと「ジェネリック型のリスト」ののような感じです。

declare
  type listClass is table of 社員%rowtype;
  list listClass;
begin
  select * bulk collect into list from 社員;
end;

このように使えるみたいです。次に、このリストを、戻り値として返す例です。

create package foo is
  -- リスト型の定義
  type listClass is table of 社員%rowtype;
  -- リスト型を返す関数の定義
  function bar return listClass;
end;

create or replace package body foo is

  function bar return listClass is
    -- リスト型オブジェクトを定義
    list listClass;
  begin
    -- bulk collect into を使って代入
    select * bulk collect into list from 社員;

    return list;
  end;
  
end;

見慣れない「bulk collect into 〜」を使う以外は、かなり直感的なプログラムだと思います。また、リストの要素型には以下のように、ユーザ定義型を指定することもできるようです。

create package foo is
  -- リストの要素型の定義
  type rowClass is record (id number, name varchar2(10));  
  -- リスト型の定義
  type listClass is table of rowClass;

ここでは「record」型として、ユーザ定義の型を定義しています。

ちなみに、functionの呼び出し元では、以下のようになります。

declare
    list foo.listClass;
begin
    list := foo.bar();

    -- 取得した内容を、デバッグ出力で確認
    for i in 1 .. list.count loop
      dbms_output.put_line(list(i).name);
    end loop;
end;

smithsmith 2009/06/04 14:14 >>Ctrl+M
Category->Window の Maximize Active View or Editor に何も割り当てないようにするんですね。
参考になりました。ありがとうございます〜

こころこころ 2011/10/24 15:47 参考になりましたです。

shuntakeuch1shuntakeuch1 2018/01/22 19:58 ありがとうございます。