Это первый раз, когда я задаю здесь вопрос, но в прошлом я неоднократно использовал стек-поток, чтобы найти решения для проблем, которые возникают в моем коде.
Я работаю над страницей передачи базы данных на php-сайте, который загружает CSV-файлы и обновляет базу данных, и в зависимости от типа обновления пользователь выбирает, что эти данные могут быть обновлены / вставлены по ключу. Из-за этого я хочу запустить 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 («таблица», 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;
}
}
Я считаю, что происходит то, что драйвер базы данных в PHP предполагает, что любой вывод из соединения с базой данных (в отличие от наборов результатов, которые возвращаются отдельно) является некоторой формой ошибки. Обратите внимание, что выходные данные, которые вы получаете от SQL Server, фактически идентичны в обоих случаях, за исключением некоторой дополнительной контекстной информации. Я видел похожие проблемы, когда параметр ROW_COUNT оставлен включенным, а текстовое сообщение «строки затронуты / возвращены» интерпретируется как ошибка.
Поскольку команды DBCC, мягко говоря, не очень стандартизированы, я сомневаюсь, что есть какой-либо способ подавить это сообщение на стороне SQL Server. Однако, поскольку вы знаете, что на самом деле это не ошибка, вы должны просто игнорировать ее на стороне PHP. Вы уже подавляете собственный механизм ошибок PHP с помощью @
оператор, так что просто нужна версия вашего Query
метод без or $this->error(sqlsrv_errors());
,
Кстати, это хороший пример тщательного разделения обязанностей: поскольку класс абстракции базы данных взял на себя ответственность за форматирование ошибки в HTML и ее отображение пользователю, вы более или менее вынуждены изменить или заменить эту логику. , Если вместо этого он вызвал исключение, ваш вызывающий код может перехватить этот конкретный случай, в то время как другие могут перейти к глобальному обработчику ошибок, который соответствующим образом отформатировал сообщение.
Других решений пока нет …