Codeigniter: sql срабатывает только при изменении текстового поля в форме обновления

#codeigniter

#codeigniter

Вопрос:

У меня проблема с формой обновления. Это форма «сведения о клиенте», в которой поля предварительно заполняются данными из базы данных.

По сути, форма обновляется только при изменении текстового поля, т. Е. Отправленное текстовое поле имеет значение, отличное от предыдущего. Если вы этого не сделаете, например, ничего не измените или просто установите флажок, форма отправляет переменные в модель, но модель, похоже, не выполняет sql.

После тестирования я знаю, что форма отправляет данные, и я знаю, что модель их получает. Просто, похоже, он вообще не выполняет запрос. affected_rows() равен нулю и не возвращает ошибок.

Как будто CI проверяет перекрестные проверки полей перед выполнением SQL.

Но если вы измените текстовое поле, все будет работать гладко — хорошо.

Мой код огромен, поэтому я опубликую резюме:

Контроллер

 if ($this->form_validation->run() == FALSE)
{
 //load views etc
}
else
{
  $title = $this->input->post('title');
  $forename = $this->input->post('forename');
  //etc...
  $this->load->model('Clients_model');

  $update_sql = $this->Clients_model->update_client(
                           $title,
                           $forename,
                           $surname,
                           $dob,
                           $email,
                           $address1,
                           $address2,
                           $town,
                           $county_state_id,
                           $address_code,
                           $country_id,
                           $alt_address1,
                           $alt_address2,
                           $alt_town,
                           $alt_county_state_id,
                           $alt_address_code,
                           $alt_country_id,
                           $use_alt_address,
                           $phone_land,
                           $phone_mobile,
                           $client_type,
                           $cancer_profile,
                           $communication_method,
                           $involvement,
                           $status,
                           $client_id
  );
  $this->session->set_flashdata('msg', $update_sql);
  redirect('/clients', 'refresh');
}  
  

Модель

 function update_client($title,
                     $forename,
                     $surname,
                     $dob,
                     $email,
                     $address1,
                     $address2,
                     $town,
                     $county_state_id,
                     $address_code,
                     $country_id,
                     $alt_address1,
                     $alt_address2,
                     $alt_town,
                     $alt_county_state_id,
                     $alt_address_code,
                     $alt_country_id,
                     $use_alt_address,
                     $phone_land,
                     $phone_mobile,
                     $client_type,
                     $cancer_profile,
                     $communication_method,
                     $involvement,
                     $status,
                     $client_id
)
{
         $this->sql = 'UPDATE client
                       SET
                       title = ?,
                       forename = ?,
                       surname = ?,
                       dob = ?,
                       email = ?,
                       address1 = ?,
                       address2 = ?,
                       town = ?,
                       county_state_id = ?,
                       address_code = ?,
                       country_id = ?,
                       alt_address1 = ?,
                       alt_address2 = ?,
                       alt_town = ?,
                       alt_county_state_id = ?,
                       alt_address_code = ?,
                       alt_country_id = ?,
                       use_alt_address = ?,
                       phone_land = ?,
                       phone_mobile = ?,
                       status = ?
                       WHERE
                       client_id = ?
                       ';
         $this->query = $this->db->query($this->sql, array(
                   $title,
                   $forename,
                   $surname,
                   $dob,
                   $email,
                   $address1,
                   $address2,
                   $town,
                   $county_state_id,
                   $address_code,
                   $country_id,
                   $alt_address1,
                   $alt_address2,
                   $alt_town,
                   $alt_county_state_id,
                   $alt_address_code,
                   $alt_country_id,
                   $use_alt_address,
                   $phone_land,
                   $phone_mobile,
                   $status,
                   $client_id
                   ));
         if ( $this->db->affected_rows() == 1)
         {
          //etc
         }
}
  

Большое спасибо!

Джо

Ответ №1:

Все выглядит нормально, и у меня никогда не было таких проблем с использованием CI … Вы пробовали использовать Active Record, просто в качестве эксперимента? Здесь я использовал более простую версию, которая передает функции не все параметры, а только весь массив post; таким образом, вы не рискуете пропустить или удвоить некоторые параметры!

Контроллер:

   //...
 $update_sql = $this->Clients_model->update_client($this->input->post());
 //...
  

Модель:

 function update_client($post)
{
  if(!is_array($post))
  { 
     return 'error in passing POST data';
  }
  $fields = array ('title' => $post['title'], 'forename' => $post['forname'], ....);
  $client_id = $post['client_id'];
  $this->db->where('client_id',$client_id);
  $this->db->update('client',$fields);
}    
  

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

1. Спасибо, Дэмиен, я просто просматривал активную запись раньше. Мне понравилось, но в руководстве не показано, что вы можете экранировать значения в предложении WHERE . Я вижу из вашего примера, что это возможно. Я думаю, что теперь я буду использовать его.

2. Активная запись автоматически экранирует каждое значение; для не слишком сложных запросов, подобных этому, это довольно удобно и безопасно, а также быстрее. Сообщите, решит ли это вашу проблему

3. Я попробовал подход с активной записью и, к сожалению, точно такой же результат. Однако я создал обходной путь: я просто добавил избыточное поле — ‘modified’ в таблицу БД. Затем я заставил контроллер отправить текущую дату в модель. Похоже, это «пробуждает» SQL модели. Но сейчас я все об активной записи. Так намного лучше. Я оглядываюсь на себя прежнего, который не использовал active record, и думаю: «Кто был тот парень?» Кем он был? И я смотрю на него сверху вниз с презрительным взглядом. Большое спасибо Дэмиену Джо

4. Странно, что это не работает, на самом деле, мне это никогда не приходило в голову. Возможно, вы захотите опубликовать его на форумах CodeIgniter или опубликовать трек ошибок, кто знает. LOL, я тоже считаю активную запись спасением жизни (и времени!)!

5. Я получил ответ от форума codeigniter. Согласно ‘Kamarg’, большинство баз данных не выполняют обновление, если в данных нет изменений. Для меня это было новостью. Это имеет смысл, но мне все равно нужно было, чтобы он сработал, поскольку я также обновлял связанные таблицы. Спасибо.