Как минимизировать дублирование кода в sql-запросе?

Я работаю над кодом запроса SQL, в котором хочу избежать дублирования запроса sql.

Ниже приведен код запроса sql:

    switch ($y) {
        case 'l.text':
            $query->order('numeric_text ' . (strtolower($x) == 'DESC' ? 'DESC' : 'ASC') .
                ', ' . $y . ' ' . (strtolower($x) == 'DESC' ? 'DESC' : 'ASC'));
            break;
    }

В приведенном выше коде SQL-запроса strtolower($x) == 'DESC' ? 'DESC' : 'ASC' используется в двух местах. Думаю вместо этого поставить варибал.

Вот что я пробовал:

    $sortOrder = (strtolower($x) == 'DESC' ? 'DESC' : 'ASC');

    switch ($y) {
        case 'l.text':
            $query->order('numeric_text ' . $sortOrder . ', ' . $y . ' ' . $sortOrder);
            break;
    }



Постановка задачи:

Мне интересно, есть ли другой лучший способ, мы можем избежать дублирования запросов sql.

То, что вы делаете сейчас, мне кажется нормальным. Одна небольшая оптимизация может использовать преимущество того, что порядок сортировки ASC является сортировкой по умолчанию, если не указан ни ASC, ни DESC. Итак, вы можете использовать: $sortOrder = (strtolower($x) == 'DESC' ? 'DESC' : '')

Tim Biegeleisen 26.10.2018 05:06

Я должен сказать, что strtolower($x) будет никогда равняться 'DESC'. Может, хочешь strtoupper($x)? Кроме того, если strtoupper($x) может принимать только значения 'ASC' или 'DESC', вы можете просто использовать $x непосредственно в запросе, поскольку SQL не заботится о случае.

Nick 29.10.2018 03:25

Если $ x не DESC, что это еще может быть? :)

Zee 29.10.2018 04:34

@ Джон, это единственная часть, которую вы хотите сжать? Как и Тим, я считаю, что для написания СУХОГО кода переменные уже используются надлежащим образом. Я обычно стараюсь избегать подробных блоков переключения, но для них свое время и место. Я думаю, вы слишком много думаете об этом. У вас в блоке переключателей много корпусов? Это большая проблема с точки зрения дублирования? Вы применили свои собственные методы запросов к базе данных или используете хорошо известный фреймворк?

mickmackusa 29.10.2018 22:25

Вам, вероятно, следует предоставить немного больше информации. например, сколько всего случаев? Насколько велика судьба между разными делами? Сколько у вас дублирования кода? Есть ли экземпляры дублирования кода, отличные от того, который имеет sortOrder? Это все вопросы, на которые нужно ответить, если вы хотите получить наилучший ответ о том, как вы можете оптимизировать свой код. Я имею в виду, что то, что вы сделали с порядком сортировки, пока правильно, но мне кажется, что за вашим вопросом скрывается нечто большее. В противном случае вы бы просто дали ответ, который дали сами.

Benjamin Basmaci 30.10.2018 14:59

Награда? В самом деле ? для этой проблемы !, это даже не проблема. Это больше похоже на предпочтение стиля кодирования. Джон, то, что вы сделали, идеально, не тратьте зря время, чувак, у вас все еще есть миллионы строк кода, которые ждут вас, чтобы написать.

Accountant م 04.11.2018 02:02
6
6
502
4

Ответы 4

Возможно, вы можете использовать функцию в своей модели или вспомогательной библиотеке, чтобы выполнить эту работу за вас, и использовать ее в своем проекте, это может быть хорошей идеей СУШИТЬ свой код.

// Helper

function sort_statment($fields, $sort_order) {
  $sort_statment = '';
  foreach($fields as $field){
     $sort_statment += $field . ' ' . $sort_order 
  }
  return $sort_statment;
}


// Model 
$sort_fields ['numeric_text', 'other_field', $y ....];

switch ($y) {
    case 'l.text':
        $query->order(sort_statment($sort_fields, $sort_order);
        break;
}

Как Ник, упомянутый в комментариях, вы не можете уменьшить строку и сделать ее равной 'DESC' или 'ASC', предполагая, что это всего лишь опечатка, вы можете просто перезаписать свою переменную вместо объявления новой:

    if(strtoupper($x) != 'DESC') $x = 'ASC';

switch ($y) {
    case 'l.text':
        $query->order('numeric_text ' . strtoupper($x) . ', ' . $y . ' ' . strtoupper($x));
        break;
}

Также было бы полезно узнать, какие значения может принимать $ x.

если вы хотите минимизировать дублирование кода, вы можете разделить код на три части: определение порядка сортировки, определение имени столбца и создание запроса. Например:

// determination of sort order
$sortOrder = (strtoupper($x) == 'DESC' ? 'DESC' : 'ASC');


// determination of column name
switch ($y) {
    case 'l.text':           
        $column = 'numeric_text';
        break;
}

// making of a query
$query->order($column . $sortOrder . ', ' . $y . ' ' . $sortOrder);

Конечно, вы можете создавать функции или методы (если вы используете ООП) с этими частями кода. Например:

/**
 * determination of sort order
 */
function getSortOrder($x)
{
    return strtoupper($x) == 'DESC' ? 'DESC' : 'ASC';
}

/**
 * determination of column name
 */
function getColumn($y)
{
    switch ($y) {
        case 'l.text':           
            return 'numeric_text';
            break;
    }
}

/**
 * making of a query
 */
function addOrder($query, $x, $y) 
{
    $sortOrder = getSortOrder($x);
    $column = getColumn(y);
    $query->order($column . $sortOrder . ', ' . $y . ' ' . $sortOrder);
}

Кроме того, если у вас много столбцов, вы можете использовать сопоставление вместо оператора case. Это сделает ваш код более удобным для чтения. Например:

// determination of column name
$map = [
   'l.text' => 'numeric_text'
];
$column = key_exists($y, $map) ? $map[$y] : 'default_column'

Почему бы вам не использовать стенографию тернарного оператора?

<?php
$sortOrder = $sortOrder ?: 'ASC';

switch ($y) {
    case 'l.text':
        $query->order("numeric_text {$sortOrder},{$y} {$sortOrder}");
        break;
}

Потому что это было бы то же самое, что вообще не проверять $sortOrder (за исключением крайнего случая, когда он является ложным или неопределенным). (Допускается, что исходный код - неправильный и равен всегда установке порядка сортировки на ASC ...)

LSerni 04.11.2018 13:06

Другие вопросы по теме