PHP : SQLExpress 2005 接続と通常処理

  PDO と COM



PHP のオンラインマニュアルには以下のように記述されています

>Windows では、Microsoft SQL Server や Sybase データベースにアクセスする際には
>PDO_ODBC ドライバを使用すべきです。 Windows 版のネイティブの DB-LIB は時代遅れになっており、
> スレッドセーフではない上に Microsoft にもサポートされていません。

どういう事が実際やってみると、php_pdo_mssql.dll は、以前の php_mssql.dll と同じ dll を呼び出しており
エラーになってしまいます。で、PDO_ODBC でテストしました。また、Windows ベースですと、 COM を使って
ADO 経由でアクセスするのもかなり前から運用していますが特に問題無く動きます
( Field オブジェクトを使った更新はできませんし、フィールド名参照でエラーになりますが )







  SQS2005_PDO_ODBC.php



ループ中の更新に別接続が必要でした、一般的に DB の レコードセットの扱いによっていろいろなパターンが
ありますが、まずその環境内で動くかどうかという事を確かめるのが重要です。それからオプションやメソッドを
調査してチューニング可能ならば変更していけば良いと思います。( デッドロックの可能性は考慮すべきです )

  
<?
$strDriver = "{SQL Native Client}";
$strTarget = "NIGHT_TCP";	// 別名
$strDB = "lightbox";
$strUser = "sa";
$strPass = "passwordpassword";

// **********************************************************
// Windows 用動的ロード
// **********************************************************
if ( !extension_loaded( "pdo" ) ) {
	dl("php_pdo.dll");
}
if ( !extension_loaded( "pdo_odbc" ) ) {
	dl("php_pdo_odbc.dll");
}

// **********************************************************
// 接続
// **********************************************************
$Cn = new PDO(
	"odbc:Driver=$strDriver;Server=$strTarget;" .
	"Database=$strDB;Uid=$strUser;Pwd=$strPass;");
$Cn2 = new PDO(
	"odbc:Driver=$strDriver;Server=$strTarget;" .
	"Database=$strDB;Uid=$strUser;Pwd=$strPass;");


$Query = "select * from [社員マスタ]";

// **********************************************************
// レコードセット
// ※ メタデータは取得できませんでした
// **********************************************************
$handle = fopen( ".\\社員マスタ.csv", "w" );

$Rs = $Cn->Query( $Query );

$nFields = $Rs->columnCount();
$hbuffer = "";
$update_cnt = 0;
while( $result = $Rs->fetch(PDO::FETCH_ASSOC) ) {
	if ( $hbuffer == "" ) {
		$field_names = array_keys($result);
		for( $i = 0; $i < $nFields; $i++ ) {
			if ( $hbuffer != "" ) {
				$hbuffer .= ",";
			}
			$hbuffer .= $field_names[$i];
		}
		fwrite( $handle, $hbuffer . "\n" );
	}

	$buffer = "";
	for( $i = 0; $i < $nFields; $i++ ) {
		if ( $buffer != "" ) {
			$buffer .= ",";
		}
		$buffer .= $result[$field_names[$i]];
	}
	fwrite( $handle, $buffer . "\n" );

	// 更新( 別接続 )
	$day = ($update_cnt % 5) + 1;
	$Query = "update [社員マスタ] set [生年月日] = '2005/01/0$day'";
	$Query .= " where [社員コード] = '{$result['社員コード']}'";
	$Cn2->exec( $Query );
	// false がエラーです。 0 は、実行が成功しても対象が無かった場合に返ってきます
	// ですから、if ( !$ret ) は正しくありません
	if ($ret===false) {
		print_r( $Cn->errorInfo() );
	}

	$update_cnt++;

}

// **********************************************************
// ファイルクローズ
// **********************************************************
fclose( $handle );
// **********************************************************
// 接続解除
// **********************************************************
$Cn2 = null;
$Cn = null;
?>
  



  SQS2005_COM_OLEDB.php

純正接続と、2種類の SQLServer ドライバでテストしています。
何故か、SQL Native Client では、追加オプションで Trusted_Connection=yes 
が必要でした。エラーメッセージからするとバグっぽくて、上記は回避策でしか無いように思いますが・・・
また、名前付きパイプにすると動くのは、前者はいかにもバグっぽいです。

※ フィールド名で参照できないのは不便なので、連想配列に代入しなおしています

  
<?
// **********************************************************
// SQLExpress 2005 / OLE DB / 純正接続
// COM(ADO) : 読み込みと更新
// **********************************************************
$Cn = new COM( "ADODB.Connection" );
$Cn->CursorLocation = 3;
$Rs = new COM( "ADODB.Recordset" );
				
$strTarget = "NIGHT_TCP";	// 別名
$strDB = "lightbox";
$strUser = "sa";
$strPass = "passwordpassword";

// **********************************************************
// 接続文字列
// **********************************************************
$ConnectionString =
	"Provider=SQLOLEDB;" .
	"Data Source=$strTarget;" .
	"Initial Catalog=$strDB;" .
	"User ID=$strUser;" .
	"Password=$strPass;";

/*
// ODBC 接続 / {SQL Server}
$strDriver = "{SQL Server}";
// SQL Server は、TCP/IP と 名前付きパイプで接続されました
$ConnectionString =
	"Provider=MSDASQL;" .
	"Driver=$strDriver;" .
	"SERVER=$strTarget;" .
	"DATABASE=$strDB;" .
	"USER=$strUser;" .
	"PWD=$strPass;";
*/

/*
// ODBC 接続 / {SQL Native Client}
$strDriver = "{SQL Native Client}";
// TCP/IP で接続するのに、Trusted_Connection=yes; が必要でした
// http://technet.microsoft.com/ja-jp/library/ms130822(SQL.90).aspx
// 上記指定が無い場合、名前付きパイプでは接続されました
// $strTarget = "lbox";	// 名前付きパイプの別名
$ConnectionString =
	"Provider=MSDASQL;Trusted_Connection=yes;" .
	"Driver=$strDriver;" .
	"SERVER=$strTarget;" .
	"DATABASE=$strDB;" .
	"USER=$strUser;" .
	"PWD=$strPass;";
*/

// **********************************************************
// 接続
// **********************************************************
$Cn->Open( $ConnectionString );

$Query = "select * from [社員マスタ]";

// **********************************************************
// レコードセット
// **********************************************************
$handle = fopen( ".\\社員マスタ.csv", "w" );

// レコードセットが開いていたら、閉じておく
if ( $Rs->State >= 1 ) {
	$Rs->Close();
}
$Rs->Open( $Query, $Cn );

$nFields = $Rs->Fields->Count;
$hbuffer = "";
$update_cnt = 0;
while( !$Rs->EOF ) {
	if ( $hbuffer == "" ) {
		for( $i = 0; $i < $nFields; $i++ ) {
			if ( $hbuffer != "" ) {
				$hbuffer .= ",";
			}
			$hbuffer .= $Rs->Fields[$i]->Name;
		}
		fwrite( $handle, $hbuffer . "\n" );
	}

	$buffer = "";
	for( $i = 0; $i < $nFields; $i++ ) {
		if ( $buffer != "" ) {
			$buffer .= ",";
		}
		$buffer .= $Rs->Fields[$i]->Value . "";

		// 日本語名称で直接参照できないので、連想配列を作成
		$Column[$Rs->Fields[$i]->name] = $Rs->Fields[$i]->value;

	}
	fwrite( $handle, $buffer . "\n" );

	// 更新( 別接続 )
	$day = ($update_cnt % 6) + 1;
	$Query = "update [社員マスタ] set [生年月日] = '2005/01/0$day'";
	// 連想配列で値を参照
	$Query .= " where [社員コード] = '{$Column["社員コード"]}'";
	$Cn->execute( $Query );

	$Rs->MoveNext();
	$update_cnt++;

}

// **********************************************************
// ファイルクローズ
// **********************************************************
fclose( $handle );
// **********************************************************
// 接続解除
// **********************************************************
@$Cn->Close();
?>
  












  infoboard   管理者用   
このエントリーをはてなブックマークに追加





フリーフォントWEBサービス
SQLの窓WEBサービス

SQLの窓フリーソフト

素材

一般WEBツールリンク

SQLの窓

フリーソフト

JSライブラリ