0

ここで質問するのはこれが初めてですが、過去にスタックオーバーフローを何度も使用して、コードで発生した問題の解決策を見つけました。

私はcsvファイルをアップロードしてデータベースを更新するphpサイトのデータベース転送ページに取り組んでおり、ユーザーが選択した更新の種類に応じて、このデータをキーで更新/挿入できます。このため、更新が行われた後に DBCC CHECKIDENT を実行して、テーブル内の最大のキーの後に新しいエントリが正しくインクリメントされるようにしたいと考えています。

これは私が実行しているphpコードです:

$getMaxID = new Query("SELECT MAX($tableKeys[$t]) as max from $t", __LINE__, __FILE__);
$maxID = $getMaxID->result(0,'max');
$result = new Query("DBCC CHECKIDENT ('$t', RESEED, $maxID)", __LINE__, __FILE__);

$t は、テーブル名の配列に格納されているテーブル名です。

このコードから次のエラーが発生します。

There has been a system error. We apologize for the inconvienience.
Error Details: [Microsoft][SQL Server Native Client 11.0][SQL Server]Checking identity information: current identity value '16', current column value '16'.
Line #: 615
File: C:\OCPOS\htdocs\OCPOS\menuTransfer\importMenu.php
Query: DBCC CHECKIDENT ('table', RESEED, 16)

私を混乱させているのは、ペースト DBCC CHECKIDENT ('table', RESEED, 16) をサーバー管理スタジオにカットすると、それが機能し、次のようになることです。

Checking identity information: current identity value '16', current column value '16'.
DBCC execution completed. If DBCC printed error messages, contact your system administrator.

誰かがこれを引き起こしている考えを持っている場合、またはこの問題に対処するために私が見逃した投稿がある場合は、どんな助けも大歓迎です.

以下はクエリクラスです。私はそれをしませんでした:

class Query{
    var $stmt; //hold link to result
    var $queryStr; //hold string
    var $queryLine;
    var $queryFile;

    function Query($str, $line, $file)
    {
      global $conn;
      $this->queryStr = $str;
      $this->queryLine = $line;
      $this->queryFile = $file;   
      $this->stmt = @sqlsrv_query($conn, $this->queryStr, array(), array("Scrollable" => SQLSRV_CURSOR_KEYSET)) or $this->error(sqlsrv_errors());
    }

    function error($var)
    {
        echo "
        <p style='border: 1px solid #c00; margin: 5px; padding: 5px;'>
        There has been a system error. We apologize for the inconvienience.<br/>
        Error Details: ". $var[0]['message'] ."<br/>
        Line #: $this->queryLine<br/>
        File: $this->queryFile<br/>
        Query: $this->queryStr<br/>
        </p>
        ";
    }

    function fetch_array()
    {
      $array = sqlsrv_fetch_array($this->stmt);
      if(is_array($array))
        return $array;
      else
      {
        return false;
      }
    }

    function fetch_assoc_array()
    {
      $array = sqlsrv_fetch_array($this->stmt, SQLSRV_FETCH_ASSOC);
      if(is_array($array))
        return $array;
      else
      {
        return false;
      }
    }


    function num_rows()
    {
      return sqlsrv_num_rows($this->stmt);
    }

    function numrows()
    {
      return $this->num_rows();
    }

    function result($row, $var)
    {
      $array = sqlsrv_fetch_array($this->stmt, SQLSRV_FETCH_ASSOC, SQLSRV_SCROLL_FIRST);
      return $array[$var];              
    }

      function all() {
          $return = array();
          while ($tmp = $this->fetch_array()) {
              $return[] = $tmp;
          }
          return $return;
      }


      function arr() {
          return $this->fetch_array();
      }

      function getAll() {
          $return = array();
          while ($tmp = $this->fetch_array()) {
              $return = array_merge($return, $tmp);
          }
          return $return;
      }

      function extract($var) {
          $rv = array();
          while ($tmp = $this->fetch_array()) {
              $rv[] = $tmp[$var];
          }
          return $rv;
      }

  }
4

1 に答える 1

0

PHP のデータベース ドライバは、(個別に返される結果セットとは対照的に) データベース接続からの出力は何らかのエラーであると想定しているためです。SQL Server から得られる出力は、いくつかの追加のコンテキスト情報を除いて、実際には 2 つのケースで同じであることに注意してください。ROW_COUNT 設定をオンのままにしておくと、同様の問題が発生し、テキストの「影響を受けた行/返された行」メッセージがエラーとして解釈されます。

DBCC コマンドは、うまく言えばあまり標準化されていないため、SQL Server 側でこのメッセージを抑制する方法はないと思います。ただし、実際にはエラーではないことがわかっているため、PHP 側では単純に無視できるはずです。PHP 自体のエラー メカニズムは演算子ですでに抑制されている@ため、必要なのはQueryメソッドのバージョンのor $this->error(sqlsrv_errors());.

ちなみに、これは責任を慎重に分離することの価値を示す良い例です。データベース抽象化クラスがエラーを HTML にフォーマットしてユーザーに表示する責任を負っているため、多かれ少なかれそのロジックを変更または置換する必要があります。 . 代わりに、例外がスローされた場合、呼び出し元のコードはこの特定のケースをキャッチし、メッセージを適切にフォーマットしたグローバル エラー ハンドラーに他のコードを渡すことができます。

于 2015-08-24T20:06:58.793 に答える