Метод обновления Codeigniter Activerecord отказывается вставлять значение NULL

Я использую библиотеку активных записей Codeigniters для обновления столбца в моей БД.

Вот SQL для таблицы

CREATE TABLE `schedules` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`reservation_id` INT(11) NULL DEFAULT NULL,
`title` VARCHAR(255) NOT NULL,
`description` VARCHAR(512) NULL DEFAULT NULL,
`start_date` DATE NOT NULL,
`start_time` TIME NOT NULL,
`end_time` TIME NULL DEFAULT NULL,
`enabled` TINYINT(1) NULL DEFAULT '1',
`status` ENUM('OPEN','RESERVED') NULL DEFAULT 'OPEN',
PRIMARY KEY (`id`),
INDEX `fk_schedules_reservations` (`reservation_id`),
CONSTRAINT `fk_schedules_reservations` FOREIGN KEY (`reservation_id`) REFERENCES `reservations` (`id`) ON UPDATE NO ACTION ON DELETE NO ACTION

)

Я объявил reservation_id как обнуляемый (reservation_id INT(11) NULL DEFAULT NULL)

Проблема в том, что CI, похоже, не хочет отправлять значение NULL, когда я создаю оператор.

$data['status'] = $this->Schedule->get_status_open();
$data['reservation_id'] = null; 
$this->Schedule->update($s_id, $data);

Этот бит кода просто генерирует следующее сообщение об ошибке

Error Number: 1452

Cannot add or update a child row: a foreign key constraint fails (`ethyme/schedules`, CONSTRAINT `fk_schedules_reservations` FOREIGN KEY (`reservation_id`) REFERENCES `reservations` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION)

UPDATE `schedules` SET `status` = 'OPEN', `reservation_id` = '' WHERE `id` = '4'

Насколько я знаю, все, что вам нужно сделать, это установить значение NULL, и AR должен определить, что это значение NULL, но здесь это не так. Просто продолжает отправлять пустые значения.

Я новичок в CI, нужно ли мне делать что-то еще, чтобы он заработал? Любые идеи?


person JohnP    schedule 18.08.2010    source источник
comment
Это оказалось не проблемой. Базовая модель, которую я использовал, использовала xss_clean для фильтрации данных и искажала такие типы данных, как NULL, TRUE, FALSE и так далее. Добавление списка исключений решило проблему. Вышеуказанное является ПРАВИЛЬНЫМ способом отправки данных NULL.   -  person JohnP    schedule 19.08.2010


Ответы (5)


Пытаться:

$this->db->set('reservation_id', NULL);

Вполне может быть, что подход $data не любит NULL.

person Phil Sturgeon    schedule 18.08.2010
comment
превосходно! это сработало. К сожалению, это означает, что я не смогу использовать подход $data, если я не работаю с промежуточным методом, который выполняет итерацию по массиву и устанавливает данные. В любом случае, проблема решена. Спасибо за вашу помощь всем - person JohnP; 19.08.2010
comment
немного покопался, оказалось, что xss_clean поглощал мои данные. Добавлен список исключений для типов данных, чтобы он игнорировал NULL, TRUE, FALSE. Похоже, использование было правильным в конце концов :/ - person JohnP; 19.08.2010
comment
Да, я подумал, что это может быть ошибка, но я знал, как это работает. Можете ли вы отправить ошибку в средство отслеживания проблем CodeIgniter на BitBucket, и я постараюсь внести исправление в ядро. Кроме того, вы можете сколько угодно смешивать $data и -›set(). - person Phil Sturgeon; 24.08.2010
comment
@JohnP, как вы добавили список исключений? - person Jonah; 29.08.2012
comment
@Jonah Я только что изменил метод validate() в своей базовой модели. Это применимо только в том случае, если вы используете одну и ту же базовую модель. - person JohnP; 29.08.2012

Я справился с этим следующим образом: расширил класс CI_Model с помощью этого метода для обработки нулей. Вы должны вызывать его каждый раз, когда ожидаете null. Я не так часто использую нули, поэтому этот метод подходит, когда мне нужно установить нулевое значение. Просто передайте строку «NULL» из массива данных. Это сбрасывает элемент массива и устанавливает его в кэш активной записи.

     class MY_Model extends CI_Model {

      public function __construct() {
          parent::__construct();
      }

      /* Handles null values for active record data array.  If 
       * $dataarray[$data_key] is string 'NULL',
       * use active record set method to set null and unset the 
       * string 'NULL'.  $data_array is by reference.
       * @param - array   the data array
       * @param - data_key - string  the key to be evaluated */
      protected function handle_null_active_record(&$data_array, $data_key){
        if ('NULL'==$data_array[$data_key]){
          $this->db->set($data_key, null);
          unset($data_array[$data_key]);
        }
      }

    }
person steampowered    schedule 16.09.2011

В CI ключевое слово NULL всегда должно быть в верхнем регистре. Попробуйте это простое изменение и посмотрите, работает ли оно. См. соответствующую часть руководства пользователя здесь.

person musoNic80    schedule 18.08.2010
comment
нет, я тоже пробовал раньше, все равно не работает. Поскольку это нулевой тип данных, я не думаю, что случай в любом случае имел бы большое значение. - person JohnP; 18.08.2010
comment
Это часть руководства по стилю и ни на что не влияет. - person Phil Sturgeon; 18.08.2010

Ваш столбец reservations_id ссылается на столбец id в таблице бронирований, верно? Вы проверили, что столбец в таблице reservstions также может иметь нулевое значение? Если это первичный ключ и автоматически увеличивается, то это вполне может быть проблемой. Я не думаю, что вы можете иметь столбец как нулевой в одной таблице, если он обозначен как внешний ключ для столбца, который не может быть нулевым в ссылочной таблице. Я ясно объяснил это для вас?

person musoNic80    schedule 18.08.2010
comment
Это не проблема, потому что я выполнил запрос вручную с нулевым значением вместо кавычек, и он работал нормально. Мне просто нужно иметь возможность отправлять нулевое значение вместо пустого. Если не считать превращения этого в пользовательский запрос, ничего не приходит на ум. - person JohnP; 18.08.2010

Из документации CI 3.0.0:

set() также принимает необязательный третий параметр ($escape), который предотвратит экранирование данных, если установлено значение false.

$this->db->set('reservation_id', 'NULL', false);
person Abdulqader Kapadia    schedule 19.04.2015