0

(PHPを使用して)ディレクトリをウォークし、ファイルの変更および作成された時刻を取得し、必要に応じてSQLServer2003テーブルを更新または挿入しようとしています。

DirectoryIteratorこれを行うためにPHPを使用していますが、オブジェクトの関数のみを使用すれば問題なく動作します。getCTime()インクルードするか、代わりにオブジェクトgetMTime()メソッドを使用するように移動すると、SQLServerは挿入/更新時にエラーをスローします。

22003:[Microsoft] [SQL Server Native Client 10.0][SQLServer]式をデータ型smalldatetimeに変換する際の算術オーバーフローエラー。

getMTime()このエラーは、オブジェクトメソッドを使用している場合にのみ発生します。Testdirには、明らかにテストするためだけに2つのファイルがあります。

私はGoogleを介して、特にStackoverflow(OneTwoThree)でこれに関するヘルプを検索しました。ただし、これらのStackOverflowの質問はSELECTステートメントに関するものでCONVERTあり、SQLの関数を使用すると言っています。私が見つけた唯一の準関連項目は、SQLユーザーがデフォルトの言語を適切に設定していることを確認するためのブログ投稿でした。私のユーザーの場合、「英語」に正しく設定されています。

関数全体とそれに続く呼び出しは次のとおりです。

function fillArrayWithFileNodes( DirectoryIterator $dir )
{
  $data = array();
  require('connecttodbfile');
  clearstatcache();

  foreach ( $dir as $node )
  {
    if ( $node->isDir() && !$node->isDot() )
    {
      $data[$node->getFilename()] = fillArrayWithFileNodes( new DirectoryIterator( $node->getPathname() ) );
    }
    else if ( $node->isFile() )
    {

        $filename = $node->getFilename();
        //Comment this out below and use CTime, Update works!

        //$file_time = date('Y-d-m H:i:s', $node->getMTime());


        //Comment this out and use MTime, Update DOES NOT WORK!
        $file_time = date('Y-d-m H:i:s', $node->getCTime()); 



        //Debug here, make sure I'm getting expected values 

        echo sprintf("Mtime (%s): %s - %s<br />Ctime (%s):  %s - %s<br /> <br />", gettype($node->getMTime()), $node->getMTime(), gettype($node->getMTime()), date('Y-d-m H:i:s', $node->getMTime()), $node->getCTime(), date('Y-d-m H:i:s', $node->getCTime()));


        $data[] = array('time'=>$file_time);

        try {


        $sQuery = <<<EOD
BEGIN TRAN
UPDATE files SET file_time=:ftime WHERE file_name=:fname

IF @@ROWCOUNT = 0 and @@ERROR = 0
   BEGIN
    INSERT INTO files (file_name,file_time) VALUES (:f_name, :f_time)
   END
COMMIT TRAN
EOD;

        $statm = $conn->prepare($sQuery);

        //PDO doesn't like it if we name repeat variables the same. So even if you use the same variable more than once in your query, PDO says you need the exact number of variables in the execute array as is in your statement, all unique names.

        $statm->execute(array(':ftime'=> $file_time, ':fname'=>$filename,':f_time'=> $file_time, ':f_name'=>$filename));


    } catch(PDOException $err) {//SQL got mad at us. Figure out why.
        echo $statm->errorCode() . " : ";
        $error = $statm->errorInfo();
        print_r( $error[2]);
        exit(1);
     }
    }
  }
  return $data;
}

$fileData = fillArrayWithFileNodes( new DirectoryIterator( 'C:\testdir' ) );

echo "<pre>";

print_r($fileData);

echo "</pre>";

このコードを(Webブラウザーを介して)mtimeとして実行すると$file_time、次の出力が得られます。

Mtime (integer): 1311599068 - 2011-25-07 08:04:28 
Ctime (integer): 1346941012 - 2012-06-09 09:16:52

22003 : [Microsoft][SQL Server Native Client 10.0][SQL Server]Arithmetic overflow error converting expression to data type smalldatetime.

$file_time代わりに使用するように変更した場合getCTime()、出力はエラーなしで完了します。

Mtime (integer): 1311599068 - 2011-25-07 08:04:28 
Ctime (integer): 1346941012 - 2012-06-09 09:16:52
Mtime (integer): 1265983000 - 2010-12-02 07:56:40 
Ctime (integer): 1346941018 - 2012-06-09 09:16:58


Array (
    [0] => Array
        (
            [time] => 2012-06-09 09:16:52
        )

    [1] => Array
        (
            [time] => 2012-06-09 09:16:58
        )

)

StackOverflowの質問(上記のリンク)で指定されたメソッドが両方のケースで適切mtimectimeアップロードされたとしても、私の質問はまだ変更なしで機能するのになぜ機能しないのですか?ctimemtime

4

1 に答える 1

2

SQL ServerはYYYY-MM-DDを必要としているため、あなたの場合はYYYY-DD-MMを送信しています。mdateは2011-25-07を提供しますが、25は有効な月ではないため、YYYY-MM-DDの有効な日付ではありません。2012-06-09が返され、06が有効な月であるため、cdateが機能しているのは偶然です。フォーマットを変更するか、サーバーの日付ローカリゼーションを変更する必要があります。

于 2012-09-07T00:57:24.477 に答える