カテゴリー
PHP SQL ただの現状記述 (Daily Activities) インターネット一般 (Internet General) プログラミング (Programming)

昨日よりぶったまげました

いやあ 昨日この現象に気づきました 原因精査にもう一杯一杯となってしまったのです 色々な懸案事項をそっちのけで原因究明に身も心も取られてしまいました

しかし、突然閃きが起こり全て解決しました。それは西暦年号が当然ながら現在は 2020年であり、2019年ではないからだったのです。

現在、鎌倉ライブデモンストレーションの Home Pageにアクセスして例えばコメディカル・セッションを覗いて下さい

そうするとこんなふうにもぬけの殻状態のページが見えるでしょう

もぬけの殻のページ
もぬけの殻のページ

我ながら最初にこの画面見た時、「あーっ、とてつもなく良くないことが起こっている、ページを乗っ取られたのかな」と頭の中が真っ白でした。冷静になり、local serverで動かしても同様なのです。これはおかしい、サーバーを乗っ取られたのであれば、ローカルでも同じ現象が出るのはおかしい、そのように考えました。

そして今朝、シンガポールでコーヒーを飲みながらテストしていて気が付きました。それは kamakuralive.net全体の設定ページに仕込んである次の一文です

$this_year = date('Y');

これにより例えば 次のSQL文が発行され、データベースからデータを読み込むのです

$stmt = $pdo->prepare( "SELECT * FROM `session_tbls2019` WHERE `class` = 'com' AND `year` = '" . $this_year . "' ORDER BY `sessionNo` ASC;" );

要するに、プログラムを時間経過から独立させるために、わざわざ $this_yearという変数を設定し、それを用いているのです。

当然のことながら、現在の date(‘Y’); という文は、’2020’を返します。従って、それに従う SQL文ではデータが無く、空白となるのでした。つまり年号が 2019年から 2020年に変わった途端に見かけ上データが表示されなくなるのでした。でもこれっていいことですね。昔のページが自動的に消失するに等しいのですから・・・

カテゴリー
SQL ただの現状記述 (Daily Activities) コンピューター (Computer) プログラミング (Programming)

すぐ忘れる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;

 

カテゴリー
PHP SQL インターネット一般 (Internet General) コンピューター (Computer) プログラミング (Programming)

思いがけないエラー原因

メルアドというのはある個人の 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()関数により整数型に変換せねばならないのです これに気づくのに相当の時間がかかりました

カテゴリー
PHP インターネット一般 (Internet General) コンピューター (Computer) プログラミング (Programming)

Excelデータを二次元配列に読み込む

今 成田空港に向かう NEXの中でテストを走らせています もちろん Objectとして Excelの行や列を扱うのも良いのですが、MySQL側はあくまでも二次元配列という概念ですので、今後のために2次元配列に変換します その部分を作成しました

require '../vendor/autoload.php';

use PhpOffice\ PhpSpreadsheet\ Spreadsheet;
use PhpOffice\ PhpSpreadsheet\ Writer\ Xlsx as Writer;
use PhpOffice\ PhpSpreadsheet\ Reader\ Xlsx as Reader;
use PhpOffice\ PhpSpreadsheet\ Cell\ Coordinate;

$reader = new Reader();
//$reader->setInputEncoding('SJIS');
$spreadsheet = $reader->load( 'poster2018.xlsx' );
//$reader->setInputEncoding('SJIS');
$sheet = $spreadsheet->getActiveSheet();

$lines = array();
$max_row = 0;	// 今rowの最大数値
$max_column = 0;	// 	columnの最大値
$nlines = array(); // Columnを数字にした二次元配列

$row_counter = 0;
$column_counter = 0;
foreach($sheet->getRowIterator() as $row) {
  foreach($sheet->getColumnIterator() as $column) {
    $lines[$row_counter][$column_counter] = $sheet->getCell( $column->getColumnIndex() . $row->getRowIndex() )->getValue();
    // これで$linesという2次元配列に Excel dataが集積された
    // これからは $lines[n][m]のような二次元配列として扱うことが可能となる
    $column_counter++;
  }
  $row_counter++;
}
$max_row = $row_counter;
$max_column = $column_counter;

ここでキモとなるのが、Excelではそれぞれのセル座長は A1より始まる表記となっていることです 通常の二次元配列では[0][0]より始まる配列ですので、この変換が必要となります

また Excelファイルを扱う時何時も問題となるのが、文字コードです Excelでは DOSからの伝統で日本語文字コードは Shift-JISであり、現在のプログラミングで標準的な UTF-8とは合いませんし、文字化けが起こります

そこで、PhpSpreadSheetにも

$reader->setInputEncoding('SJIS');

というメソッドが定義されているのですが、最近の Excelで改善されたのか、何しろそのようなメソッドを使用せずに自動的に UTF-8に変換されるようです ですからこのメソッドは不要でした

カテゴリー
PHP SQL ただの現状記述 (Daily Activities) インターネット一般 (Internet General) コンピューター (Computer) プログラミング (Programming)

この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日間損した気分 でも自分が招いたものだから仕方ありません

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

カテゴリー
SQL ただの現状記述 (Daily Activities) インターネット一般 (Internet General) コンピューター (Computer) プログラミング (Programming)

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;

 

カテゴリー
PHP SQL インターネット一般 (Internet General) プログラミング (Programming)

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文から正しい件数を知ることができます

 

カテゴリー
PHP SQL インターネット一般 (Internet General) コンピューター (Computer) プログラミング (Programming)

二日間バグで苦しみ

どうにも納得行かなかったのです それは、http://www.tri-international.orgのサイトをサーバー移行した時に始まったのです

そもそもこちらの都合でサーバー移行したのではありません サーバー運営会社の意向に沿って移行したのです これまでずっと使用してきた Rental Serverは FirstServerだったのですが、それが時代の移り変わりと共に、Zenlogicという次世代のサーバー環境になったのです 正直僕はここら Cloudとか詳しくないので何が違うのか良く分かりません

この移行の時に、これまでの全データも移行したのですが、問題は MySQL Database Server Dataだったのです これも移行したのですが、それと共に phpMyadminという MySQLサーバーデータ管理の秀逸のソフトがそのままでは作動しなくなり、改めてインストール必要でした そしてこの時に、port 3307にインストールされたのです これが問題だったのです

そもそも現在はMySQL5.1が port 3307で作動し、MySQL5.0が port 3306で作動している、という変な状況が続いているのです だいたい port番号なんて普段意識せずに使っているのですよっ

そしてサーバー移行前のデータは MySQL5.0から MySQL5.1に自動的にコピーされ、一見すると同じデータが2つの DB serverにあるのです

さて、PHPプログラムでは Internetアクセスした時には、

$db_host = '127.0.0.1';
//$db_port = '3307';//コメントアウトしているので port3306のまま
$db_user = '**A';
$db_password = '**B';

という風に 普段は port 3306の MySQL databaseに接続しているのです しかし管理ソフトの phpMyadminは port 3307で接続していたのです 当初は同じDBがコピーされていたので、phpMyadminでいくらデータをいらっても これは 3307接続ですから、PHP programからはその変更は見えません

結果的にわけのわからないことになってしまったのです この portの問題に気づくまでには丸一日かかりました そして現在は $db_port = ‘3307’; この一文を活かしているので、全てが port 3307で作動している MySQLでプログラム全体が動いているのです

いやあこのバグは判明にずいぶんかかりました しかし、僕の頭脳が未だ明晰であることが証明されてある意味嬉しいですね

カテゴリー
Ajax Javascript jQuery Mac PHP ただの現状記述 (Daily Activities) インターネット一般 (Internet General) コンピューター (Computer) プログラミング (Programming) 冠動脈インターベンション (PCI) 経橈骨動脈的冠動脈インターベンション (TRI)

Distal Radial Approach (DRA) vs Conventional Radial Approach (CRA)

さて、そろそろこの秘密のテクニックについて公表する時が来ました 何れにしてもライブでは皆の眼に触れることになるのでこれ以上秘密にしていても仕方ありません

DRAに関しては最近僕が推進している三文字略語ですが、未だ主流とはなっていません しかし、臨床試験を企画していますのでそれで主流となるでしょう dTRAとかも使われていますし、PPA (Princeps Pollicis Artery) Approachとか、も使われています これに対して通常の橈骨動脈アプローチについては、区別するために、僕は三文字略語として Conventionalを用いたいと思っています

さて、何故今 DRAが注目されるのでしょうか? 未だに経大腿動脈的冠動脈インターベンション (TFI: Trans Femoral Intervention)にこだわっている頭の固い先生方はここでは相手にはしませんが、経橈骨動脈的冠動脈インターベンション (TRI: Trans Radial Intervention)の優れた点は世界中で明らかになっています しかし、その最大の欠点は術後の橈骨動脈閉塞 (RAO: Radial Artery Occlusion)です これはTRIが生まれた時から悩ましき問題として注目されていました 既に論文にもなっている僕が仕掛けた大規模医師主導型臨床試験である RAP and BEAT trialでもこの点が Primary Endpointとされました

さて、DRAにおいては穿刺部位が何しろ CRAよりも末梢であるため、原理的にRAOが起こる可能性は低いと考えられます しかし、問題は何しろ新しい方法なのでデータがありません 想像のみで医療はできません そこで、僕はこの問題を解決するために無作為臨床試験を規格しているのです これに参加して頂ける施設と医師を求めています もちろん医師主導型臨床試験ですので、基本的にはボランティアとしての参加です 真実を知りたい、という知的意欲の下で参加して頂きたいのです

徐々にその全貌を明らかにしていきたいと思います 例によって、症例登録は Webで行います お金が無いとか色々ありますので、例によって僕が自分の知識を駆使して、html5 + css3 + Javascript + jQuery + Ajax + SQL + PHPでその全てのプログラムを書きます というよりも、既に成功裏に終了した RAP and BEAT試験のプログラムを改変するのです これが、僕が次に考えている大きな仕事です

カテゴリー
SQL インターネット一般 (Internet General) プログラミング (Programming)

何と そうだったのか

ここに二つのテーブルがあります そう、片方は doctor_tblsであり、今一つは role_tblsです 簡単にすれば

doctor_tblsは

doctor_tbl_id name is_male
1 saito 1
2 shigeru 1
3 hanako 0

このようにしましょう is_maleは性別であり、男性であれば、1 女性であれば 0としましょう

もう一つのテーブルは役割配置表 role_tblsで その構造は

role_tbl_id doctor_tbl_id role_kind
1 2 chair
2 2 speaker
3 1 moderator

のように例えばなります つまり、saitoさんは doctor_tbl_id = 1ですが、 role表の中の role_tbl_id = 3に配置されていますね そして役割は moderatorということになります これをSQL文で記述すれば

SELECT * FROM `doctor_tbls` INNER JOIN `role_tbls` 
ON `doctor_tbls`.`doctor_tbl_id` = `role_tbls`.`doctor_tbl_id`;

ということになります ここで良くあるように

role_tbl_id doctor_tbl_id role_kind
1 2 chair
2 2 speaker
3 1 moderator
4 1 speaker
5 1 chair

のようにsaitoさんの役割分担が三つに増えたとしましょう この時に、役割が2つの人を探す SQL文について考えみました なかなか正解には至らなかったのですが、色々調べてようやく分かりました それは

SELECT `dr_tbl_id`, count(`dr_tbl_id`) as `Frequency` FROM `role_tbls` group by `dr_tbl_id` HAVING `Frequency` = '2'

というものです ここで HAVING句を用いるのと、仮想列名 Frequencyというのを用いるのがミソなのです 素晴らしいですね

とにかく SQLというのはプログラミング言語の中でも異色のものであり、集合演算をするのです これを理解しないと無駄足を踏むことになりますね