Заполнение списка автозаполнения новыми тегами - PullRequest
0 голосов
/ 10 мая 2018

Я использую Lucee 5.x и Maria DB (MySQL).

У меня есть список разделенных запятыми пользователем.Мне нужно запросить базу данных, и если элемент отсутствует в базе данных, мне нужно добавить его.

предоставленный пользователем список
green blue purple white

элементы базы данных
black white red blue pink orange lime

Это неОжидается, что список базы данных вырастет до более чем 30 элементов, но конечные пользователи всегда находят «креативные» способы использования инструментов, которые мы им предоставляем.

Поэтому, используя предоставленный пользователем список выше, только green и *В базу данных необходимо добавить 1020 *.

Сравнивать ли пользовательский список с элементами базы данных или наоборот?Изменится ли процесс, если количество предоставленных пользователем списков превысит количество в базе данных (имеется в виду, если пользователь отправляет 10 элементов, а база данных содержит только 5 элементов)?Я не уверен, какой цикл является лучшим способом определить, какие элементы являются новыми.Должен быть в cfscript, и я смотрю на варианты зацикливания, как указано здесь (https://www.petefreitag.com/cheatsheets/coldfusion/cfscript/)

FOR Loop
FOR IN Loop (Array)
FOR IN Loop (Query)

Я пробовал MySQL, а не IN, но это оставило меня с существующими значениями базы данных в дополнение к новым. Я знаю, что это должно быть просто, и я где-то слишком усложняю это и / или слишком близко к проблеме, чтобы увидетьрешение.

Ответы [ 2 ]

0 голосов
/ 11 мая 2018

Опять же, поскольку это операция, которую может выполнять база данных, я бы подавал входные данные в базу данных, а затем позволял ей решать, как обращаться с несколькими ключами.Я не рекомендую использовать CF для циклического просмотра ваших значений, а затем делать INSERT.Для этого потребуется несколько поездок в базу данных и последующая обработка на сервере приложений, который на самом деле не нужен.

Я предлагаю использовать синтаксис INSERT....ON DUPLICATE KEY UPDATE... MariaDB.Это также потребует, чтобы любое поле, в которое вы пытаетесь вставить, на самом деле имело ограничение UNIQUE.Без этого ограничения самой вашей базе данных все равно, если у вас есть дубликаты данных, когда это может вызвать собственный набор проблем.

Для базы данных у нас есть

CREATE TABLE t1 (mycolor varchar(50)
  , CONSTRAINT constraint_mycolor UNIQUE (mycolor)
) ; 

INSERT INTO t1(mycolor)
VALUES ('black'),('white'),('red'),('blue'),('pink'),('orange'),('lime') 
;

. ColdFusion:

<cfscript>

myInputValues = "green,blue,purple,white" ;

myQueryValues = "" ;

function sanitizeValue ( String inVal required ) {
    // do sanitization stuff here
    var sanitizedInVal = arguments.inVal ;
    return sanitizedInVal ;
}

myQueryValues = myInputValues.listMap( 
    function(i) {
        return "('" & sanitizeValue(i) & "')" ;
    } 
) ;

// This will take parameterization out of the cfquery tag and
    preform sanitization and validation before building the 
    query string.

myQuery = new query();
myQuery.name = "myQuery";
myQuery.setDataSource("dsn");

sqlString = "INSERT INTO t1(mycolor) VALUES " 
    & myQueryValues 
    & " ON DUPLICATE KEY UPDATE mycolor=mycolor;" 
;

myQuery.setSQL(sqlString);
myQueryResult = myQuery.execute().getResult();

</cfscript>

Сначала создайте свои входные значения (myInputValues).Вы захотите выполнить проверку и очистку для них, чтобы предотвратить проникновение мерзости в вашу базу данных.Я создал функцию sanitizeValue, которая будет заполнять операции очистки и проверки.

myQueryValues станет строковым списком значений в правильном формате, который мы будем использовать для вставки в базу данных.

Затем мы просто создаем new query(), используя myQueryValues в sqlString, чтобы получить наш запрос.Опять же, поскольку мы строим строку для нескольких значений до INSERT, я не думаю, что есть способ для пользователя queryparam для этих VALUES.Но так как мы очистили нашу строку ранее, она должна делать многое из того, что cfqueryparam делает в любом случае.

Мы используем синтаксис INSERT INTO .... ON DUPLICATE KEY UPDATE ... MariaDB только для вставки уникальных значений.Опять же, это требует, чтобы у самой базы данных было ограничение для предотвращения дублирования в любом столбце, который мы вставляем.

Для демонстрации: https://dbfiddle.uk/?rdbms=mariadb_10.2&fiddle=4308da3addb9135e49eeee451c6e9e58

Это должно делать то, что вы ищете, не перегружая вашу базу данных.У меня нет сервера Lucee или MariaDB, настроенного для тестирования, поэтому вам придется попробовать его и посмотреть, как он работает.Я не знаю, насколько велика ваша база данных или станет, но запрос все равно должен выполняться довольно быстро.

0 голосов
/ 10 мая 2018

Вы можете сделать это:

  • получить список существующих предметов из базы данных
  • добавить пользовательский список
  • удалить дубликаты
  • обновить БД, если элементы были добавлены

<cfscript>

    var userItems = '"green","blue","purple","white"';
    var dbItems = '"black","white","red","blue","pink","orange","lime"';
    var result = ListRemoveDuplicates( ListAppend(dbItems, userItems));

    if (ListLen(result) neq ListLen(dbItems)) {
      // update db
    }

</cfscript>

Обновление (только новые предметы)

<cfscript>

    var userItems = '"green","blue","purple","white"';
    var dbItems = '"black","white","red","blue","pink","orange","lime"';
    var newItems = '';

    ListEach(userItems, function (item) {
        if (not ListFind(dbItems, item)) {
          newItems = ListAppend(newItems, item);
        }
    })

</cfscript>

Сценарий trycf.com:
(https://trycf.com/gist/f6a44821165338b3c10b7808606979e6/lucee5?theme=monokai)

...