Запрос MySQL с использованием Coalesce не обновит строки

#mysql #coalesce

#MySQL #coalesce

Вопрос:

У меня есть запрос MySQL, который использует COALESCE для возврата к нулевым значениям и присваивает этим нулевым значениям первое ненулевое значение, которое он находит.

Запуск этого запроса из PHP-скрипта с использованием устаревшей функции mysql_query, а также с использованием mysqli и вызова самой хранимой процедуры, строки не затрагиваются; однако, если я запускаю запрос вручную или вызываю хранимую процедуру для него вручную, строки обновляются должным образом, создавая желаемый набор результатов.

DDL:

 CREATE TABLE IF NOT EXISTS `file_index` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `file_id` int(10) unsigned NOT NULL,
  `page` int(10) unsigned NOT NULL,
  `user_id` int(10) unsigned NOT NULL,
  `made` datetime DEFAULT NULL,
  `current` tinyint(3) unsigned DEFAULT '1',
  `code` char(5) NOT NULL,
  `idnumber` int(10) unsigned DEFAULT NULL,
  `deconstructed` int(1) NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`),
  KEY `file_id` (`file_id`,`page`),
  KEY `user_id` (`user_id`),
  KEY `idnumber` (`idnumber`)
) ENGINE=MyISAM AUTO_INCREMENT=25 DEFAULT CHARSET=latin1 ROW_FORMAT=FIXED;
INSERT INTO `file_index` (`id`, `file_id`, `page`, `user_id`, `made`, `current`, `code`, `idnumber`, `deconstructed`) VALUES
    (2, 637847, 2, 473, '2014-06-23 00:00:00', 1, 'INIT', 1737929, 0),
    (3, 637847, 3, 473, '2014-06-23 00:00:00', 1, 'CONT', NULL, 0),
    (4, 637847, 4, 473, '2014-06-23 00:00:00', 1, 'INIT', 85956, 0),
    (5, 637847, 5, 473, '2014-06-23 00:00:00', 1, 'INIT', 163262, 0),
    (6, 637847, 6, 473, '2014-06-23 00:00:00', 1, 'INIT', 1171457, 0),
    (7, 637847, 7, 473, '2014-06-23 00:00:00', 1, 'INIT', 1173838, 0),
    (8, 637847, 8, 473, '2014-06-23 00:00:00', 1, 'INIT', 2264105, 0),
    (9, 637847, 9, 473, '2014-06-23 00:00:00', 1, 'INIT', 2084006, 0),
    (10, 637847, 10, 473, '2014-06-23 00:00:00', 1, 'INIT', 1298597, 0),
    (11, 637847, 11, 473, '2014-06-23 00:00:00', 1, 'INIT', 2263042, 0),
    (12, 637847, 12, 473, '2014-06-23 00:00:00', 1, 'INIT', 1288872, 0),
    (13, 637847, 13, 473, '2014-06-23 00:00:00', 1, 'CONT', NULL, 0),
    (15, 637845, 2, 79, '2014-06-23 00:00:00', 1, 'INIT', 2264143, 0),
    (16, 637845, 3, 79, '2014-06-23 00:00:00', 1, 'CONT', NULL, 0),
    (17, 637845, 4, 79, '2014-06-23 00:00:00', 1, 'INIT', 2019138, 0),
    (18, 637845, 5, 79, '2014-06-23 00:00:00', 1, 'INIT', 157726, 0),
    (19, 637845, 6, 79, '2014-06-23 00:00:00', 1, 'INIT', 2087837, 0),
    (22, 637845, 9, 79, '2014-06-23 00:00:00', 1, 'INIT', 2264118, 0),
    (23, 637845, 10, 79, '2014-06-23 00:00:00', 1, 'INIT', 2264124, 0),
    (24, 637845, 11, 79, '2014-06-23 00:00:00', 1, 'CONT', NULL, 0);
 

Ссылка на SQLFiddle: http://sqlfiddle.com /#!2/6e79d

Запрос:

 UPDATE file_index
SET idnumber = (@n := COALESCE(idnumber, @n))
ORDER BY file_id, page ASC
 

Текущий набор результатов:

  ---------- ------ ---------- 
| file_id  | page | idnumber |
 ---------- ------ ---------- 
|   637847 |    2 |  1737929 |
|   637847 |    3 |     NULL |
|   637847 |    4 |    85956 |
|   637847 |    5 |   163262 |
|   637847 |    6 |  1171457 |
|   637847 |    7 |  1173838 |
|   637847 |    8 |  2264105 |
|   637847 |    9 |  2084006 |
|   637847 |   10 |  1298597 |
|   637847 |   11 |  2263042 |
|   637847 |   12 |  1288872 |
|   637847 |   13 |     NULL |
|   637845 |    2 |  2264143 |
|   637845 |    3 |     NULL |
|   637845 |    4 |  2019138 |
|   637845 |    5 |   157726 |
|   637845 |    6 |  2087837 |
|   637845 |    9 |  2264118 |
|   637845 |   10 |  2264124 |
|   637845 |   11 |     NULL |
 ---------- ------ ---------- 
 

Желаемый набор результатов:

  ---------- ------ ---------- 
| file_id  | page | idnumber |
 ---------- ------ ---------- 
|   637847 |    2 |  1737929 |
|   637847 |    3 |  1737929 |
|   637847 |    4 |    85956 |
|   637847 |    5 |   163262 |
|   637847 |    6 |  1171457 |
|   637847 |    7 |  1173838 |
|   637847 |    8 |  2264105 |
|   637847 |    9 |  2084006 |
|   637847 |   10 |  1298597 |
|   637847 |   11 |  2263042 |
|   637847 |   12 |  1288872 |
|   637847 |   13 |  1288872 |
|   637845 |    2 |  2264143 |
|   637845 |    3 |  2264143 |
|   637845 |    4 |  2019138 |
|   637845 |    5 |   157726 |
|   637845 |    6 |  2087837 |
|   637845 |    9 |  2264118 |
|   637845 |   10 |  2264124 |
|   637845 |   11 |  2264124 |
 ---------- ------ ---------- 
 

Комментарии:

1. Обновлено на основе предложений.

2. Я не уверен в формальном определении, но здесь я думаю, что «DDL» означает инструкции CREATE И INSERT .

3. Обновлено с помощью инструкции INSERT.

4. Извините, но, учитывая, что ваша проблема касается только столбцов idnumber , file_id , и page у меня возникнет соблазн свести эту скрипку только к соответствующей информации.

Ответ №1:

По какой-то причине я должен выполнить запрос дважды, чтобы он вступил в силу и обновил строки. Странно, да, но он работает, если я запускаю его дважды.

Комментарии:

1. Я поиграл с вашей sql-скрипкой. Действительно, похоже, что это работает, если вы выполняете запрос дважды. Однако, похоже, это связано с тем, что во 2-й раз переменная @n была инициализирована (первым запросом). Если SET @n:=0; это сделано до обновления, оно также работает.