使用新标签填充自动完成列表
Populating Autocomplete list with new tags
我正在使用 Lucee 5.x 和 Maria DB (MySQL)。
我有一个用户提供的逗号分隔列表。我需要查询数据库,如果该项目不在数据库中,我需要添加它。
用户提供的列表
green
blue
purple
white
数据库项目
black
white
red
blue
pink
orange
lime
预计数据库列表不会增加到 30 多个项目,但最终用户总能找到 'creative' 方式来使用我们提供的工具。
所以使用上面的用户提供的列表,只有 green
和 purple
应该添加到数据库中。
我是否将用户提供的列表与数据库项目进行比较,反之亦然?如果用户提供的列表数量超过数据库中的数量(意味着如果用户提交 10 个项目而数据库仅包含 5 个项目),流程会改变吗?我不确定哪个循环是确定哪些项目是新项目的更好方法。需要在 cfscript 中,我正在查看此处概述的循环选项 (https://www.petefreitag.com/cheatsheets/coldfusion/cfscript/)
FOR 循环
FOR IN 循环(数组)
FOR IN 循环(查询)
我尝试了 MySQL 的 NOT IN,但除了新值之外,还剩下现有的数据库值。我知道这应该很简单,我在某个地方把它复杂化了 and/or 我太接近问题了,看不到解决方案。
你可以这样做:
- 从数据库中获取包含现有项目的列表
- 附加用户提供的列表
- 删除重复项
- 如果添加了项目则更新数据库
<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>
Update (only new items)
<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)
同样,由于这是数据库可以执行的操作,我会将输入数据提供给数据库,然后让它决定如何处理多个键。我不建议使用 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')
;
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()
,在sqlString
中使用myQueryValues
来得到我们的查询。同样,由于我们正在为 INSERT
的多个值构建一个字符串,我认为没有办法为那些 VALUES
用户 queryparam
。但是由于我们之前清理了我们的字符串,所以它应该可以完成 cfqueryparam
所做的大部分工作。
我们使用 MariaDB 的 INSERT INTO .... ON DUPLICATE KEY UPDATE ...
语法来仅插入唯一值。同样,这要求数据库本身有一个约束,以防止在我们插入的任何列中出现重复。
演示:https://dbfiddle.uk/?rdbms=mariadb_10.2&fiddle=4308da3addb9135e49eeee451c6e9e58
这应该可以完成您想要做的事情,而不会过多地破坏您的数据库。我没有设置要测试的 Lucee 或 MariaDB 服务器,因此您必须尝试一下,看看它的性能如何。我不知道您的数据库有多大或将有多大,但这应该仍然可以很快查询。
我正在使用 Lucee 5.x 和 Maria DB (MySQL)。
我有一个用户提供的逗号分隔列表。我需要查询数据库,如果该项目不在数据库中,我需要添加它。
用户提供的列表
green
blue
purple
white
数据库项目
black
white
red
blue
pink
orange
lime
预计数据库列表不会增加到 30 多个项目,但最终用户总能找到 'creative' 方式来使用我们提供的工具。
所以使用上面的用户提供的列表,只有 green
和 purple
应该添加到数据库中。
我是否将用户提供的列表与数据库项目进行比较,反之亦然?如果用户提供的列表数量超过数据库中的数量(意味着如果用户提交 10 个项目而数据库仅包含 5 个项目),流程会改变吗?我不确定哪个循环是确定哪些项目是新项目的更好方法。需要在 cfscript 中,我正在查看此处概述的循环选项 (https://www.petefreitag.com/cheatsheets/coldfusion/cfscript/)
FOR 循环
FOR IN 循环(数组)
FOR IN 循环(查询)
我尝试了 MySQL 的 NOT IN,但除了新值之外,还剩下现有的数据库值。我知道这应该很简单,我在某个地方把它复杂化了 and/or 我太接近问题了,看不到解决方案。
你可以这样做:
- 从数据库中获取包含现有项目的列表
- 附加用户提供的列表
- 删除重复项
- 如果添加了项目则更新数据库
<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>
Update (only new items)
<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)
同样,由于这是数据库可以执行的操作,我会将输入数据提供给数据库,然后让它决定如何处理多个键。我不建议使用 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')
;
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()
,在sqlString
中使用myQueryValues
来得到我们的查询。同样,由于我们正在为 INSERT
的多个值构建一个字符串,我认为没有办法为那些 VALUES
用户 queryparam
。但是由于我们之前清理了我们的字符串,所以它应该可以完成 cfqueryparam
所做的大部分工作。
我们使用 MariaDB 的 INSERT INTO .... ON DUPLICATE KEY UPDATE ...
语法来仅插入唯一值。同样,这要求数据库本身有一个约束,以防止在我们插入的任何列中出现重复。
演示:https://dbfiddle.uk/?rdbms=mariadb_10.2&fiddle=4308da3addb9135e49eeee451c6e9e58
这应该可以完成您想要做的事情,而不会过多地破坏您的数据库。我没有设置要测试的 Lucee 或 MariaDB 服务器,因此您必须尝试一下,看看它的性能如何。我不知道您的数据库有多大或将有多大,但这应该仍然可以很快查询。