Haskellに惑わされ – 6

例えばこうです 僕が良く Web programmingする時に使用する PHP言語ですが、database言語であるSQL (僕が使用しているのは open sourceの MySQL言語です)と連携してSQLサーバーよりデータを取得し、それをサーバー内で PHP言語により加工し、その結果を http通信でクライアント側 つまり、一般ユーザーに送っているのですが、その部分の肝腎の SQL serverからの PHPでのデータ取得部分の一例はこんなものです

$row_session = $stmt_session->fetch( PDO::FETCH_ASSOC );
$stmt_role = $pdo->prepare( "SELECT MAX(`created`) FROM `role_tbls`;" );
$stmt_role->execute();

ここで出てきましたよね この部分です

"SELECT MAX(`created`) FROM `role_tbls`;"

この部分を良く見ると、

`created` や`role_tbls`

のように何だかさっきのもの (`)ではさまれていますね これは実は SQL構文規則では不要なものです しかしながら、この列が SQLの列名であることを分かりやすくするためにわざわざ用いているのです

つまり、 (`)というものはプログラム解析上では何の意味も持たない飾りだということです

従ってこの部分に(‘)というものを使用すると途端に文法エラーとなりプログラムは走りません これと同様のことが Haskellでも起こるのです

すぐ忘れるmysqlコマンド

折角ターミナルで $mysqlと打ち込めば mysqlが CLI (command line interface)で立上るようになったにもかかわらず数日使わないとすっかりコマンドを忘れていました そこで自分で良く使うものをここに書いておきます

## mysql を 「ユーザー名」で立ち上げる うまく立ち上がると passwordを要求される
$mysql -p -u ユーザー名

## mysqlに既に登録されているデータベース一覧を表示
mysql> show databases;

## 「そのデータベース」を使用する
mysql> use そのデータベース;

## 「そのデータベース」のtable一覧表示
mysql> show tables;

## 「そのデータベース」の「そのtable」のフィールドを一覧表示
mysql> desc そのtable;

## mysqlを終了する
mysql> quit;

 

MacBook Pro/MAMP mysqlにパスを通すには?

MacBook Proで Laravelをいじっています 直接 MySQLにコマンドを発行せねばならない場面があり、これまで直接 MySQLをいじくっている時には、phpMyadminを立ち上げ、その中で SQLを発行していました

しかし、これは本来のやり方ではなく、本来的には MySQLコマンドを用いるべきです しかし、MAMPを使用している時にこれをどのようにすれば良いのかさっぱり分かりませんでした 金沢に移動する新幹線の中、この中は長野から富山の間は電波が通じず、インターネットアクセスに難儀するのですが、何とか調べました
$ code ~/.bashrc ## ホームの.bashrcを編集します

そしてここからは visual studio codeの中ですが、そこで以下の文を最後に追加します
export PATH="$PATH:/Applications/MAMP/Library/bin/"

そして terminalに戻りもちろんこれを叩いて反映させます

$ source ~/.bashrc

これで直接ターミナルから mysqlと打ち込めば mysqlを動作することができます 便利ですね

思いがけないエラー原因

メルアドというのはある個人の IDとしても使用できます 中にはもちろん自分個人のメルアドを作らず、一つのメルアドを共有されている方々もおられますが、この場合どんなプライベートな連絡もその人々で共有されてしまいますので、プライバシーを保つことができません

そんなメルアドの特性からメルアドは IDとして良く使用されます そして、その人が登録されているか否かの判定にはデータベースをメルアドで検索し、見つかった個数が 0であれば登録されていない、という事実を利用します つまりプログラムに書けば以下のようになります

$stmt = $pdo->prepare( "SELECT COUNT(*) FROM `doctor_tbls` WHERE `email` = :email;" );  // (A)
$stmt->bindValue( ":email", $test-email-address, PDO::PARAM_STR );   // $test-email-addressをテストするためにpdoで変数をバインドする
$flag = $stmt->execute();  
// 検索を実行する
if ( !$flag ) {        
// エラーが無いかチェックする
  $infor = $stmt->errorInfo();
  print_r( $infor );
  exit;
}
$already_registered = $stmt->fetchColumn(); 
// COUNT(*)によりそのメルアドがDBに存在するか調べる 既に登録済のメルアドであれば、0ではない
if ( intval($already_registered) === 0 ) { 
// ここからメルアドが登録されているか否かのチェックとなる
}


if ( $already_registered === 0 ) { 
// こうするとこのブロックの中に入らない
}


if ( $already_registered == 0 ) { 
// こうするとこのブロックの中にきちんと入る
}

PHPには同一性判定として ==と ===の2つがあります ===は値のみならずその型もチェックします ですから、===の方が論理的に合っていますので、通常は ===を使用すべきです しかしながらこのように DBより読み込んできたりすると見かけは数字の0であったとしても型が異なるのです ですから、きちんと作動するようにするためには intva()関数により整数型に変換せねばならないのです これに気づくのに相当の時間がかかりました

この10日間 悩み抜いたバグがようやく解決

さて、https://www.kamakuralive.net/ のWeb programを作る段階で、コメコメ部門のポスター発表部分がまだ実装できていませんでした その理由は唯一つ、僕がズルというか楽をしたいからだったのです

既にポスター演題が 20集まっており、それをコメコメ委員の方々が Excel形式で集計してくださっていました しかし、それを Web databaseである MySQLデータベースに読み込まねばなりません 実は既に昨年、 Excel (これはShift-J文字コード) の xlsx形式-> Text形式 (.txt)に変換 -> 文字コードを UTF-8に変換 -> .txtを MySQL databaseに読み込み という部分は作成していました

まあ作成といっても、foreachでループを回して読み込むだけなのですが・・・

今回は折角ですので、自分の勉強のためにもPHPSpreadSheetという Excelファイルを PHPで読み込むライブラリを用いることにしたのです

その部分は案外簡単に Excel file読み込みに成功したのですが、肝腎の MySQL databaseに書き込む SQL文がエラーが出るのです その部分のバグとりが全くうまくいかず 10日間以上を無駄に過ごしてしまいました いや 決して人生において無駄というのは無いでしょう そう思わねばやってらんないよっ

結局その部分を簡略化して出しましょう

try {
  // MySQLサーバへ接続
  $pdo = new PDO( "mysql:host=$db_host;dbname=$db_name_sessions;charset=utf8", $db_user, $db_password );
  // 注意: 不要なspaceを挿入すると' $db_host'のようにみなされ、エラーとなる
} catch ( PDOException $e ) {
  die( $e->getMessage() );
}

for ( $rowNo = 1; $rowNo < 24; $rowNo++ ) {
  $stmt = $pdo->prepare( "SELECT COUNT(*) FROM `doctor_tbls` WHERE `email` = :email;" );
  $stmt->bindValue( ":email", $nnlines[ $rowNo ][ 12 ], PDO::PARAM_STR );
  $stmt->execute();
  $count_same_email = $stmt->fetchColumn();

  if ( $count_same_email < 1 ) { // 既にこのメルアドは登録されているのでスキップ
     $stmt_dr = $pdo->prepare( "INSERT INTO `doctor_tbls` (`english_sirname`, `english_firstname`, `is_male`, `email`, `changed`) VALUES (:enlish_sirname, :enlish_firstname, :is_male, :email, :changed);" ); 
    $stmt_dr->bindValue( ":english_sirname", $nnlines[ $rowNo ][ 1 ], PDO::PARAM_STR );
    $stmt_dr->bindValue( ":english_firstname", $nnlines[ $rowNo ][ 2 ], PDO::PARAM_STR );
    
    if ( $nnlines[ $rowNo ][ 3 ] === 'M' ) {
      $sex = 1;
    } else {
      $sex = 0;
    }
    
    $stmt_dr->bindValue( ":is_male", $sex, PDO::PARAM_INT );
    $stmt_dr->bindValue( ":email", $nnlines[ $rowNo ][ 12 ], PDO::PARAM_STR );
    $stmt_dr->bindValue(":changed", date('Y-m-d H:i:s'), PDO::PARAM_STR);
    
    $flag = $stmt_dr->execute();
    
    if ( !$flag ) {
      echo "<h2 style='color:red;'>Error</h2>";
      $infor = $stmt_dr->errorInfo();
      print_r($infor);
      exit( $infor[ 2 ] );
    }
    
  }
}

これがエラーで書き込めません、色々と試みたのがうまく行きませんので、最後に  print_r($infor)の一行を加えて、SQLエラー出力を行いました

そうすると MySQL error code

SQLSTATE[HY093]

というのが出てくるのです これは検索すると パラメータの数が合わないなのですが、目を更にして見てみてもそんな訳はありません しかし、この 10日間の苦難の末ようやく発見しました

 

VALUES (:enlish_sirname, :enlish_firstname, :is_male, :email, :changed)

この部分で english_ とすべきを enlishとしているのですね このためパラメータの数が合わないため SQL errorとなっていたのです なんだかなあ パカみたい 10日間損した気分 でも自分が招いたものだから仕方ありません

本日はこれから 成田空港に向かいます このエラーを解決したのでポスター・セッション部分のプログラム完成できますね

ヘルシンキから神戸 そして WSL

WSLという言葉をご存知でしょうか Windows Subsystem for Linuxのことです

Microsoftは数年前より急速に Open Softwareに舵を切り替え、その代表として WSLという仕組みを開始したのです これは Windows10というこれまで Microsoftを支えてきた OSの中に Linuxという Open Softwareの OSをシームレスに走らせる仕組みです

もちろんこれまでに Windows10の上では、VirtualBoxや、VMWareといった有名な仮想マシン、あるいは Dockerなどのコンテナと呼ばれる仮想マシンの小型版がフリーで走っていました しかし、VirtualBoxや VMWareは Windows10の中に新たにコンピューターシステムを立ち上げるもので、マシンに対する負荷が大きいものでした

これに対して WSLというのは Windows10 OSの上に Linuxの APIを emurateする型で Linux OSを立ち上げるものです ここいら辺に関しては僕も知識がいい加減であり間違ったことも言っていると思いますので、それぞれが調べて下さい 何れにしても WSLを立ち上げたのです

その方法はネットで検索すると色々出てきますが、僕の場合、このサイトに従いました 少なくとも 2018/SEP/13の最新 Windows10 version 1803においてはこれで正しくインストールできます

とは言うもののこのサイトの後ろ半分に書かれている内容はかなり高度なものであり難解です とりあえず僕はここまで つまり、<Hyper の設定 for WSL>という部分まで行い結果的にこのような画面となりました

Linux (Ubuntu) on Windows10
Linux (Ubuntu) on Windows10 on MacOS

さて昨日は成田空港から羽田空港に移動し、伊丹空港に飛び、それから神戸の高橋病院に入りました そこで三例のPCIを行わせて頂きました

楽しく過ごしました

全く馬鹿なことをしてきた

この暑さに参っているのか頭脳の回転が遅くなっている 自分でもなんて馬鹿なんだと思うほど頭脳の回転が遅くなっている 知らない内に脳梗塞でも起こしているのだろうか?

自分の年齢から考えれば、さらには CHADS-VASCなども考慮すればその可能性は妥当である でも「自分だけはそんなことないよね」などとのほほんと構えている 自分がそんな人間だから患者さんの気持ちは痛いほど分かる そしてその気持が分かれば分かる程に患者さんのことを思う気持ちが高まっていく

とは言っても自分の頭の回転が悪いのは自分で許せない、何とか回転を早くせねばならない そんな時に立ち向かうのはやはりプログラミング でも自分はプロのプログラマではないので、アマチュアのプログラマなので、自称「アマグラマ」と呼んでいる

さてそのアマグラマが何とか少し頭の回転を取り戻したのが次の Web上での MySQLデータ修正の php program このデータというのは 実は 鎌倉ライブのweb公開用予定表 でも現在公開しているものとは不完全に修正書き換えしてあり、昨年の予定表も混在しているので混乱の的かも? まあしかし鎌倉ライブなんてそんなに世間の注目集めないのでこのまま混在していても開催までに修正すれば実害は無いのだろうと思って勝手に割り切っている

そもそも今年は鎌倉ライブ予定表のデータ構造を徐々に変更しようとしているのだ 何故ならばもっと論理的な整合性のあるデータ構造にすれば、その先修正はいらなくなるだろう と期待しているから

とりあえず、テーブルのカラムを一つ増やし、そのカラムに別のカラム上のデータを変換しながらコピーするプログラムを phpで書いたのである ばっかみたいなプログラムだけと暫くプログラム書くことから遠ざかっていたので書いている内にプログラミングの感覚が戻ってきてなんとなく自分が賢くなってきたように思うのだ

ということでそのプログラムの一部

$stmt = $pdo->prepare( "SELECT * FROM `session_tbls2018` WHERE '1' = '1';" );

try {
  $pdo->beginTransaction();
  $flag = $stmt->execute();
  if ( !$flag ) {
    $infor = $stmt->errorInfo();
    exit( $infor[ 2 ] );
  }

  $pdo->commit();
} catch ( Exception $e ) {
  $pdo->rollBack();
  echo "Failed to update Database" . $e->getMessage();
}
$rows = $stmt->fetchAll( PDO::FETCH_ASSOC );
$stmt1 = $pdo->prepare("UPDATE `session_tbls2018` SET `beginDate` = :beginDate WHERE `id` = :id;");

foreach ( $rows as $row ) { // 全てのデータ
  if ( ( $row[ 'id' ] > '171' )AND( $row[ 'id' ] < '186' ) ) {	//2017年 座学修正用
    $begintime = date( 'Y/m/d H:i:s', strtotime( '2017/12/09' . $row[ 'begin' ] ) );
    $stmt1->bindValue( ":beginDate", $begintime, PDO::PARAM_STR );
    $stmt1->bindValue( ":id", $row[ 'id' ], PDO::PARAM_INT );
    $stmt1->execute();
    try {
      $pdo->beginTransaction();
      $flag = $stmt1->execute();
      if ( !$flag ) {
        $infor = $stmt1->errorInfo();
        exit( $infor[ 2 ] );
      }

      $pdo->commit();
    } catch ( Exception $e ) {
      $pdo->rollBack();
      echo "Failed to update Database" . $e->getMessage();
    }
    echo $begintime . "<br>";
  }
  if ($row['id'] == 185) echo "座学が修正されました<br><br>";

 

 

行きつけのカフェで

本日は土曜日 午前中にカテ二件に参加し、12:30自転車で病院の裏側に向かいました ここは「藤沢市村岡」という地名ですが、とにかく長い上り坂が続きます

頑張って登りきり、いつも遠くから見ていた小高い林の場所まで登りました そこた誰も居ない場所ですが、なかなか良い見晴らしでした

しばし休んでから今度は下り坂を自転車飛ばしました そして 13:00に行きつけの「深沢」にある「栄和堂」というブック・カフェに入りました 頼んだのはコーヒー一杯のみ

そして、MacBook Proを開いて JTVT2019のプログラムに取り掛かりました 色々なことがありなかなか取り組めないでここまで時間が過ぎてしまいました もう本気にならないとやばいのです

しかし、またまた訳の分からないエラーに1.5時間悩まされました それは画面の切り替えにおいて、セッション変数が保持されない、というエラーです 原因は2つ以上ありそうなのですが、やっと一つを潰し、変則手で一つ何とかしました 最初の 1.5時間悩んだエラーの原因は、session_start()を最初に書かなかったからであり、これは僕のミスです

しかし、変則手の方は未だに良く分かりません $_SESSION変数に書き込んこだものの一部しか次のページに引き継がれないのです 今までこんなこと見たことありません ブラウザの問題かと色々なブラウザ試みたのですがどうもそうではありません $_SESSION変数の容量の問題でしょうか? でもそんなに大きなデータをセッションに溜め込んではいません 未だに分かりません原因が

変則手で解決したのは仕方なく $_POSTで渡し、渡されたページでは再度 MySQLを起動してデータをデータベースから読み込むというものです まあこれで動作するので良いと言えば良いのですが・・・

何だかすっきりしませんねえ

JTVT2019現在のデータベース構造

まだまだ refineせねばならないと思いますが、現段階での Database DDLを記録しておきます

 ###############################################################################################
 ### SQL for JTVT2019 
 ### Based on this DDL, the program is constructed.
 ### Programmed by Shigeru SAITO, MD, FACC, FSCAI, FJCC
 ### on March 4th, 2018.
 ### revised on April 12th, 2018
 ###
 ### DB Name : jtvt2019
 ###############################################################################################

CREATE TABLE IF NOT EXISTS `hp_tbls` (
  `id` INT( 11 ) NOT NULL AUTO_INCREMENT,
  `hp_code` VARCHAR( 11 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '',
  `hp_name` VARCHAR( 128 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '',
  `zip_code` VARCHAR( 7 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '',
  `ken_name` VARCHAR( 10 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '',
  `hp_address` VARCHAR( 256 )CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '',
  `country_code` TINYINT( 2 ) NOT NULL DEFAULT '1',			/* Country Code; By using this code , 1: JAPAN*/
                              /* interface such as feet or lb can be aplied. >10: feet/lb */
  PRIMARY KEY (`id`),
  UNIQUE(`hp_code`)
) ENGINE = InnoDB CHARACTER SET utf8 COLLATE utf8_general_ci AUTO_INCREMENT=0;

CREATE TABLE IF NOT EXISTS `dr_tbls` (
  `id` INT( 11 ) NOT NULL AUTO_INCREMENT,
  `kanji_sirname` VARCHAR( 64 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '',
  `kanji_firstname` VARCHAR( 64 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '',	
  `english_sirname` VARCHAR( 64 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '',
  `english_firstname` VARCHAR( 64 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '',	
  `hp_tbl_id` INT( 11 ) NOT NULL DEFAULT '0',
  `hp_name`  VARCHAR( 128 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '',
  `job_kind` TINYINT( 2 ) NOT NULL DEFAULT '1',
  `email` VARCHAR( 128 ) NOT NULL DEFAULT '',
  `dr_pwd` VARCHAR( 512 ) NOT NULL DEFAULT '',
  `clue` TINYINT( 1 ) NOT NULL DEFAULT '1',
  `hint` VARCHAR( 512 )NOT NULL DEFAULT '',
  `login_date` DATE NOT NULL DEFAULT '0000-00-00 00:00:00',
  `ip` VARCHAR( 15 ) NOT NULL DEFAULT '000.000.000.000',
  `dr_url` VARCHAR( 60 ) NOT NULL DEFAULT '',
  `is_active` BOOLEAN NOT NULL DEFAULT '0',
  `is_usable` BOOLEAN NOT NULL DEFAULT '1',
  `is_deleted` BOOLEAN NOT NULL DEFAULT '0',
  `created` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
  `modified` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
  PRIMARY KEY (`id`),
  UNIQUE(`email`),
  INDEX(`email`)
) ENGINE = InnoDB CHARACTER SET utf8 COLLATE utf8_general_ci AUTO_INCREMENT=0;

CREATE TABLE IF NOT EXISTS `login_logs` (
  `id` INT( 11 ) NOT NULL AUTO_INCREMENT,
  `dr_tbl_id` INT( 11 ) NOT NULL DEFAULT '0',
  `login_date` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
  `login_ip` VARCHAR( 15 ) NOT NULL DEFAULT '000.000.000.000',
  PRIMARY KEY(`id`),
  INDEX(`dr_tbl_id`)
) ENGINE = InnoDB CHARACTER SET utf8 COLLATE utf8_general_ci AUTO_INCREMENT=0;

CREATE TABLE IF NOT EXISTS `abstract_tbls` (
  `id` INT( 11 ) NOT NULL AUTO_INCREMENT,
  `hp_tbl_id` INT( 11 ) NOT NULL DEFAULT '0',
  `dr_tbl_id` INT( 11 ) NOT NULL DEFAULT '0',
  `submission_date` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
  `abstract_topic1` tinyint( 2 ) NOT NULL default '0', /* TAVI, MitraClip, etc  */
  `abstract_topic2` tinyint( 2 ) NOT NULL default '0', /* Complications, etc  */
  `abstract_title` VARCHAR( 200 ) NOT NULL DEFAULT '',
  `abstract_content` VARCHAR( 2000 ) NOT NULL DEFAULT '',
  `is_selected` BOOLEAN NOT NULL DEFAULT '1',
  `is_deleted` BOOLEAN NOT NULL DEFAULT '0',
  `created` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
  `modified` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
  `last_access_date` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=0;

CREATE TABLE IF NOT EXISTS `time_slot_tbls` (
  `id` INT( 11 ) NOT NULL AUTO_INCREMENT,
  `begin_time` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
    `end_time` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',	
  PRIMARY KEY (`id`)
) ENGINE = InnoDB CHARACTER SET utf8 COLLATE utf8_general_ci AUTO_INCREMENT=0;

CREATE TABLE IF NOT EXISTS `dr_role_tbls` (
  `id` INT( 11 ) NOT NULL AUTO_INCREMENT,
  `dr_tbl_id` INT( 11 ) NOT NULL DEFAULT '0',
  `time_slot_tbl_id` INT( 11 ) NOT NULL DEFAULT '0',
  `session_tbl_id` INT( 11 ) NOT NULL DEFAULT '0',
  `role_kind` tinyint( 2 ) NOT NULL default '0',
  `is_active` BOOLEAN NOT NULL DEFAULT '0',
  `is_usable` BOOLEAN NOT NULL DEFAULT '1',
  `is_deleted` BOOLEAN NOT NULL DEFAULT '0',
  `created` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
  `modified` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
  PRIMARY KEY (`id`)
) ENGINE = InnoDB CHARACTER SET utf8 COLLATE utf8_general_ci AUTO_INCREMENT=0;

CREATE TABLE IF NOT EXISTS `session_tbls` (
    `id` INT( 11 ) NOT NULL AUTO_INCREMENT,
  `session_typing_japanese` VARCHAR( 100 ) NOT NULL DEFAULT '',
  `session_typing_english` VARCHAR( 100 ) NOT NULL DEFAULT '',
    `session_sub_title_japanese` VARCHAR( 100 ) NOT NULL DEFAULT '',
  `session_sub_title_english` VARCHAR( 100 ) NOT NULL DEFAULT '',
  `session_begin_time` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
    `session_end_time` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',	
  `session_objective_japanese` VARCHAR( 300 ) NOT NULL DEFAULT '',
  `session_objective_english` VARCHAR( 300 ) NOT NULL DEFAULT '',
  `is_deleted` BOOLEAN NOT NULL DEFAULT '0',
  `created` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
  `modified` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
  PRIMARY KEY (`id`)
) ENGINE = InnoDB CHARACTER SET utf8 COLLATE utf8_general_ci AUTO_INCREMENT=0;

 

SELECTで選択した列数を PDOで PHPに渡すには

これはしばしば行う間違いなのですが、気が付かないと結構しつこいバグの原因となりますね

$sql = "SELECT COUNT(*) FROM `dr_tbl` WHERE `email` = :email AND `conf_id` = :conf_id;";
$stmt = $pdo->prepare($sql);
$stmt->bindValue(":email", $_SESSION['email'], PDO::PARAM_STR);
$stmt->bindValue(":conf_id", $_SESSION['conf_id'], PDO::PARAM_INT);
$stmt->execute();
    //$rowCount = $stmt->rowCount();
    //echo 'Executed!'.$rowCount.'<br>';
if ($stmt->fetchColumn() > 0) {	// 既に登録されているので弾く
        // この時 fetchColumn()が戻す値は SQL文で得られた count(*)ということになります
        // この結果 SELECT文から正しい件数を知ることができます