用新标签填充自动完成列表

3bygqnnd  于 2021-06-25  发布在  Mysql
关注(0)|答案(2)|浏览(409)

我正在使用Lucee5.x和MariaDB(mysql)。
我有一个用户提供的逗号分隔列表。我需要查询数据库,如果该项不在数据库中,我需要添加它。
用户提供的列表 green blue purple white 数据库项 black white red blue pink orange lime 预计数据库列表不会增长到超过30项,但最终用户总能找到“创造性”的方法来使用我们提供给他们的工具。
所以使用上面用户提供的列表 green 以及 purple 应添加到数据库中。
我是否将用户提供的列表与数据库项进行比较,反之亦然?如果用户提供的列表计数超过数据库中的值(即如果用户提交10个项目,而数据库仅包含5个项目),进程是否会更改?我不确定哪个循环是确定哪些项目是新的更好的方法。需要在cfscript中,我正在查看这里概述的循环选项(https://www.petefreitag.com/cheatsheets/coldfusion/cfscript/)
for循环
for in-loop(数组)
for in循环(查询)
我尝试了mysql的not in,但是除了新的数据库值之外,还剩下了现有的数据库值。我知道这应该很简单,而且我在某个地方把它复杂化了,而且/或者离问题太近了,看不到解决方案。

5lhxktic

5lhxktic1#

你可以这样做:
从数据库中获取包含现有项的列表
附加用户提供的列表
删除重复项
如果添加了项,则更新数据库

<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)

e5nqia27

e5nqia272#

同样,因为这是数据库可以执行的操作,所以我会将输入数据提供给数据库,然后让它决定如何处理多个键。我不建议使用cf循环检查值,然后执行 INSERT . 这将需要多次访问数据库,然后在应用服务器上处理实际上并不需要的内容。
我的建议是用mariadb的 INSERT....ON DUPLICATE KEY UPDATE... 语法。这还要求您尝试插入的任何字段实际上都有一个 UNIQUE 对它的限制。如果没有这个约束,那么您的数据库本身就不关心您是否有重复的数据,因为这会导致它自己的一系列问题。
对于数据库,我们有

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

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

冷融合是:

<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() ,使用 myQueryValuessqlString 得到我们的询问。再说一次,因为我们要为多个值构建一个字符串 INSERT ,我认为没有办法 queryparam 为了那些 VALUES . 但既然我们早些时候清理了我们的字符串,它应该做什么呢 cfqueryparam 不管怎样。
我们用mariadb的 INSERT INTO .... ON DUPLICATE KEY UPDATE ... 只插入唯一值的语法。同样,这要求数据库本身有一个约束,以防止在我们插入的任何列中重复。
对于演示:https://dbfiddle.uk/?rdbms=mariadb_10.2&fiddle=4308da3addb9135e49eeee451c6e9e58
这应该可以做你想做的事情,而不会对你的数据库造成太大的破坏。我没有设置lucee或mariadb服务器来进行测试,所以您必须尝试一下,看看它的性能如何。我不知道你的数据库有多大,但这个查询应该还是很快的。

相关问题