トップ > ODBC経由でデータベースと接続するには

Win32::ODBCを使ったサンプルスクリプト



#!c:/perl/bin/perl
# odbc.cgi
# last update:2003/06/14

$url = 'http://'.$ENV{'HTTP_HOST'}.$ENV{'SCRIPT_NAME'};
$charcode = 'sjis';
$fontsize = '8pt';

$title = '名簿データ一覧表\';      #タイトル
$dsn = 'DSN=test';                 #データソース名
$tablename = 'meibo';              #テーブル名
$recordkey = 'ID';                 #キー項目名
$ins_tsset = '登録日';             #登録日時をセットする項目名
$upd_tsset = '';                   #更新日時をセットする項目名
@readonly = ('登録日');            #入力不可の項目名
@hide     = ();                    #表示しない項目名 

if($ENV{'REQUEST_METHOD'} eq "POST") {
  read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
} else {
  $buffer = $ENV{'QUERY_STRING'};
}
@pairs = split(/&/, $buffer);
foreach $pair(@pairs) {
  ($key, $value) = split(/=/, $pair);
  $key   =~ tr/+/ /;
  $key   =~ s/%([0-9A-Fa-f][0-9A-Fa-f])/pack("C", hex($1))/eg;
  $value =~ tr/+/ /;
  $value =~ s/%([0-9A-Fa-f][0-9A-Fa-f])/pack("C", hex($1))/eg;
  $FORM{$key} = $value;
}
&init if(!$FORM{'cmd'});

&html_header;

use Win32::ODBC;
if(!($OBJ = new Win32::ODBC($dsn))) {
  print Win32::ODBC::Error();
  print "\n</body>\n</html>\n";
  exit;
}

@tablename = $OBJ->TableList;
foreach(@tablename) {
  if($tablename eq $_) {
    $find = 1;
    break;
  }
}
if(!$find) {
  print "テーブルが見つかりません。($tablename)\n";
  print "</body>\n</html>\n";
  exit;
}

$sql = "SELECT * FROM $tablename";
$OBJ->Sql("$sql");
@fn = $OBJ->FieldNames();
$fn = @fn;
%type = $OBJ->ColAttributes(SQL_COLUMN_TYPE_NAME);
foreach(keys(%type)) {
  $type{$_} =~ tr/a-z/A-Z/;
}

@euc_fn = @fn;
if($charcode ne 'euc') {
  eval{ require "./jcode.pl"; };
  if($@){
    print "jcode.plを読み込むことができません。($@)";
    print "\n</body>\n</html>\n";
    exit;
  }
  foreach(@euc_fn) {
    &jcode::convert(\$_, 'euc', $charcode);
  }
  foreach(@readonly) {
    &jcode::convert(\$_, 'euc', $charcode);
  }
  foreach(@hide) {
    &jcode::convert(\$_, 'euc', $charcode);
  }
}

if   ($FORM{'cmd'} eq 'list')   { &frame1; }
elsif($FORM{'cmd'} eq 'init')   { &frame2; }
elsif($FORM{'cmd'} eq 'insert') { &insert; }
elsif($FORM{'cmd'} eq 'read')   { &read;   }
elsif($FORM{'cmd'} eq 'update') { &update; }
elsif($FORM{'cmd'} eq 'delete') { &delete; }
else {
  print "不正なコマンドがリクエストされました。($FORM{'cmd'})\n";
  print "</body>\n</html>\n";
  exit;
}

sub frame1 {
  if($FORM{'query'}) {
    @pairs = split(/;/, $FORM{'query'});
    foreach $pair(@pairs) {
      ($key, $value) = split(/->/, $pair);
      if   ($type{$key} eq 'VARCHAR')  { $query .= " AND $key='$value'"; }
      elsif($type{$key} eq 'LONGCHAR') { $query .= " AND $key='$value'"; }
      elsif($type{$key} eq 'COUNTER')  { $query .= " AND $key=$value"; }
      elsif($type{$key} eq 'INTEGER')  { $query .= " AND $key=$value"; }
      elsif($type{$key} eq 'DECIMAL')  { $query .= " AND $key=$value"; }
      elsif($type{$key} eq 'DATETIME') { $query .= " AND $key={ts '$value'}"; }
    }
    $query =~ s/^\sAND\s//;
  } else {
    if($type{$recordkey} eq 'VARCHAR')  {
      $query = "$recordkey>='$FORM{'code1'}' AND $recordkey<='$FORM{'code2'}'";
    } else {
      $query = "$recordkey>=$FORM{'code1'} AND $recordkey<=$FORM{'code2'}";
    }
  }
  $sql = "SELECT * FROM $tablename WHERE $query ORDER BY $recordkey";
  $OBJ->Sql("$sql");
  print <<END_HTML;
<script language="JavaScript"><!--
function check() {
  if((document.f1.code1.value == "") || (document.f1.code2.value == "")) {
    alert("$recordkeyを入力してください。");
    document.f1.code1.focus();
    return(false);
  }
}
function edit(query) {
  var url;
  url = '$url?cmd=read&$recordkey=' + query;
  top.frame2.location.href = url;
}
// --></script>
<form name="f1" action="$url" method="POST" onsubmit="return check()">
 <font size="3"><b>$title</b></font>
 <input type="hidden" name="cmd" value="list">
 <input type="text" name="code1" value="$FORM{'code1'}"> 〜 
 <input type="text" name="code2" value="$FORM{'code2'}"> 
 <input type="submit" value="検索"> $query
</form>
<table width="100%" border="0" bordercolor="#a9a9a9" cellspacing="1" cellpadding="1">
 <tr bgcolor="#e6e6ff">
  <th> </th>
END_HTML

  for($i = 0; $i < $fn; $i++) {
    next if(grep(/$euc_fn[$i]/, @hide));
    print "  <th>$fn[$i]</th>\n";
  }
  print " </tr>\n";
  while($OBJ->FetchRow()) {
    %data = $OBJ->DataHash();
    $cnt++;
    $cnt2 = sprintf("%02d", $cnt);
    print " <tr bgcolor=\"#efefff\">\n";
    print "  <td><input type=\"button\" value=\"$cnt2\" onClick=\"javascript:edit('$data{$recordkey}')\"></td>\n";
    for($i = 0; $i < $fn; $i++) {
      next if(grep(/$euc_fn[$i]/, @hide));
      if($data{$fn[$i]} eq '') {
        print "  <td> </td>\n";
      } else {
        print "  <td>$data{$fn[$i]}</td>\n";
      }
    }
    print " </tr>\n";
  }
  $OBJ->Close();
  print <<END_HTML;
</table>
</body>
</html>
END_HTML
  exit;
}

sub insert {
  &frame2_from_set;
  if($type{$recordkey} eq 'VARCHAR') {
    $query = "$recordkey='$FORM{$recordkey}'";
  } else {
    $query = "$recordkey=$FORM{$recordkey}";
  }
  $sql = "SELECT * FROM $tablename WHERE $query";
  $OBJ->Sql("$sql");
  if($OBJ->FetchRow()) {
    $msg = "$recordkey '$FORM{$recordkey}'は登録されています。";
  } else {
    $data{$ins_tsset} = &datetime if($ins_tsset);
    $sql = "INSERT INTO $tablename";
    for($i = 0; $i < $fn; $i++) {
      $field .= ", $fn[$i]";
      if($data{$fn[$i]} eq '') {
        $data .= ", NULL";
      } else {
        $data .= ", '$data{$fn[$i]}'";
      }
    }
    $field =~ s/^,\s//;
    $data =~ s/^,\s//;
    $sql .= "("."$field".") VALUES("."$data".")";
    if($OBJ->Sql("$sql")) {
      $msg = $OBJ->Error();
      $msg .= " $sql";
    } else {
      &frame2_from_clear;
      $msg = "$recordkey '$FORM{$recordkey}'を登録しました。";
    }
  }
  $OBJ->Close();
  &frame2;
  exit;
}

sub read {
  &frame2_from_set;
  if(!$query) {
    if($type{$recordkey} eq 'VARCHAR') {
      $query = "$recordkey='$FORM{$recordkey}'";
    } else {
      $query = "$recordkey=$FORM{$recordkey}";
    }
  }
  $sql = "SELECT * FROM $tablename WHERE $query";
  $OBJ->Sql("$sql");
  if(!$OBJ->FetchRow()) {
    $msg = "$recordkey '$FORM{$recordkey}'は登録されていません。";
  } else {
    %data = $OBJ->DataHash();
    $status = 'edit';
    $msg = "$recordkey '$FORM{$recordkey}'を修正してください。";
  }
  $OBJ->Close();
  &frame2;
  exit;
}

sub update {
  &frame2_from_set;
  if($type{$recordkey} eq 'VARCHAR') {
    $query = "$recordkey='$FORM{$recordkey}'";
  } else {
    $query = "$recordkey=$FORM{$recordkey}";
  }
  $sql = "SELECT * FROM $tablename WHERE $query";
  $OBJ->Sql("$sql");
  if(!$OBJ->FetchRow()) {
    $msg = "$recordkey '$FORM{$recordkey}'は登録されていません。";
  } else {
    $data{$upd_tsset} = &datetime if($upd_tsset);
    for($i = 0; $i < $fn; $i++) {
      next if($fn[$i] eq $recordkey);
      if($data{$fn[$i]} eq '') {
        $data .= ", $fn[$i]=NULL";
      } else {
        $data .= ", $fn[$i]='$data{$fn[$i]}'";
      }
    }
    $data =~ s/^,\s//;
    $sql = "UPDATE $tablename SET $data WHERE $query";
    if($OBJ->Sql("$sql")) {
      $msg = $OBJ->Error();
      $msg .= " $sql";
    } else {
      &frame2_from_clear;
      $msg = "$recordkey '$FORM{$recordkey}'を更新しました。";
    }
  }
  $OBJ->Close();
  &frame2;
  exit;
}

sub delete {
  &frame2_from_set;
  if($type{$recordkey} eq 'VARCHAR') {
    $query = "$recordkey='$FORM{$recordkey}'";
  } else {
    $query = "$recordkey=$FORM{$recordkey}";
  }
  $sql = "SELECT * FROM $tablename WHERE $query";
  $OBJ->Sql("$sql");
  if(!$OBJ->FetchRow()) {
    $msg = "$recordkey '$FORM{$recordkey}'は登録されていません。";
  } else {
    $sql = "DELETE FROM $tablename WHERE $query";
    if($OBJ->Sql("$sql")) {
      $msg = $OBJ->Error();
      $msg .= " $sql";
    } else {
      &frame2_from_clear;
      $msg = "$recordkey '$FORM{$recordkey}'を削除しました。";
    }
  }
  $OBJ->Close();
  &frame2;
  exit;
}

sub frame2_from_set {
  for($i = 0; $i < $fn; $i++) {
    $data{$fn[$i]} = $FORM{$fn[$i]};
  }
}

sub frame2_from_clear {
  for($i = 0; $i < $fn; $i++) {
    $data{$fn[$i]} = '';
  }
}

sub frame2 {
if($status eq 'edit') {
  $btn2 = 'disabled'; $btn3 = 'disabled';
} else {
  $btn4 = 'disabled'; $btn5 = 'disabled';
}
  print <<END_HTML;
<script language="JavaScript"><!--
function search() {
  var i, n, query, url;
  n = document.f1.elements.length;
  query = '';
  for(i = 0; i < $fn; i++) {
    if(document.f1.elements[i].value != '') {
      query = query + document.f1.elements[i].name + '->' + document.f1.elements[i].value + ';';
    }
  }
  if(query == '') {
    alert("1つ以上の項目に入力してください。");
    document.f1.elements[0].focus();
    return;
  }
  url = '$url?cmd=list&query=' + query;
  top.frame1.location.href = url;
}

function insert() {
  if(document.f1.$recordkey.value == '') {
    alert("$recordkeyを入力してください。");
    document.f1.$recordkey.focus();
    return;
  }
  document.f1.cmd.value = 'insert';
  document.f1.submit();
}

function read() {
  if(document.f1.$recordkey.value == '') {
    alert("$recordkeyを入力してください。");
    document.f1.$recordkey.focus();
    return;
  }
  document.f1.cmd.value = 'read';
  document.f1.submit();
}

function update() {
  document.f1.cmd.value = 'update';
  document.f1.submit();
}

function del() {
  var flag;
  flag = confirm("削除してよろしいですか?");
  if(flag) {
    document.f1.cmd.value = 'delete';
    document.f1.submit();
  } else {
    return;
  }
}

function form_clear() {
  document.f1.cmd.value = 'init';
  document.f1.submit();
}
// --></script>
<form name="f1" action="$url" method="POST">
<table width="100%" border="0" bordercolor="#a9a9a9" cellspacing="1" cellpadding="0">
END_HTML
  for($i = 0; $i < $fn; $i++) {
    next if(grep(/$euc_fn[$i]/, @hide));
    print " <tr>\n";
    print "  <td width=\"20%\" bgcolor=\"#e6e6ff\"><b>$fn[$i]</b></td>\n";
    print "  <td width=\"20%\" bgcolor=\"#e6e6ff\"><b>$type{$fn[$i]}</b></td>\n";
    print "  <td width=\"35%\" bgcolor=\"#efefff\">";
    if(($status eq 'edit' && $fn[$i] eq $recordkey) || (grep(/$euc_fn[$i]/, @readonly))) {
      print "<input type=\"text\" name=\"$fn[$i]\" value=\"$data{$fn[$i]}\" size=\"40\" readonly></td>\n";
    } else {
      print "<input type=\"text\" name=\"$fn[$i]\" value=\"$data{$fn[$i]}\" size=\"40\"></td>\n";
    }
    print "  <td width=\"25%\" bgcolor=\"#efefff\">$msg{$fn[$i]}</td>\n";
    print " </tr>\n";
  }
  print <<END_HTML;
 <tr>
  <td colspan=2><center>
   <input type="hidden" name="cmd"    value="">
   <input type="hidden" name="status" value="$status">
   <input type="button" value="検索" $btn1 onClick="javascript:search()"> 
   <input type="button" value="追加" $btn2 onClick="javascript:insert()"> 
   <input type="button" value="呼出" $btn3 onClick="javascript:read()"> 
   <input type="button" value="更新" $btn4 onClick="javascript:update()"> 
   <input type="button" value="削除" $btn5 onClick="javascript:del()"> 
   <input type="button" value="クリア" onClick="javascript:form_clear()">
  </center></td>
  <td colspan=2><font color="#ff0000">$msg</font></td>
 </tr>
</table>
</form>
</body>
</html>
END_HTML
}

sub init {
  print "Content-type: text/html\n\n";
  print <<END_HTML;
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
<title>$title</title>
</head>
 <frameset rows="50%,*">
  <frame src="$url?cmd=list" name="frame1">
  <frame src="$url?cmd=init" name="frame2">
 </frameset>
</html>
END_HTML
  exit;
}

sub html_header {
  print "Content-type: text/html\n\n";
  print <<END_HTML;
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
<title>$title</title>
<style type="text/css">
<!--
body, th, td {
  font-size: $fontsize;
  color: #000000;
}
-->
</style>
</head>
<body bgcolor="#ffffff" text="#000000">
END_HTML
}

sub datetime {
  local($sec, $min, $hour, $day, $mon, $year, $weekday) = localtime(time);
  local($date);
  $date = sprintf("%04d-%02d-%02d %02d:%02d:%02d", $year+1900, $mon+1, $day, $hour, $min, $sec);
  return $date;
}

©J.Kitaoka