首页 > 解决方案 > 如何在不存在的地方插入记录,如果存在则通过使用mysql或knex和express js忽略它

问题描述

如果值已经存在,我想检查我的数据库,然后不要添加相同的值,如果不存在添加这个新值。

我的代码

router.post('/additem', function(req, res, next){
  db('types').insert({type_name: req.body.getypename}).where('type_name', '!=', req.body.getypename).then(()=>{
     res.redirect('/additem?success=1')
  }).catch((err)=>{ res.redirect('/additem?'+err) })
})

标签: mysqlexpressknex.js

解决方案


欢迎来到 Stackoverflow!

使用.count()是在添加记录之前检查记录是否存在的一种方法。请参阅下面的函数countTypeNameRec作为示例。

然后下面的函数addTypeNameRec将计数和插入放在一起,首先检查记录的计数,然后如果它为零,则添加记录。

有关使用 .count()的更多详细信息,请参阅Knex .count() 参考.count()。(对于大型未索引表,使用select * where xxx limit 1可能是更好的性能选择。)

第二种方法: 我认为这是一个硬性规则,即您不能拥有具有重复“type_name”字段值的“type”表记录。如果是这种情况,那么通过数据库中的 SQL 表定义将该字段设置为主键(或在该字段的表上创建唯一索引)也将防止用户创建重复记录。在这种情况下,该.insert()语句将在重复记录上引发错误。但是,如果您想给用户一个可以理解的“值已经存在”错误消息,那么解释错误有点混乱。是关于该问题的讨论。

如果您不关心向用户返回一个他们可能无法理解的丑陋的原始数据库错误,那么您可以以一种简单的方式使用第二种方法,只需insertTypeNameRec从路由代码而不是函数调用addTypeNameRec函数(跳过计数检查)。

编码

// count the records
//
function countTypeNameRec(input_type_name) {
   return db('types')
    .count('*')
    .where('type_name', input_type_name)
    .then((data)=>{
            return data[0].count
        })
}

// insert a new record
//
function insertTypeNameRec(input_type_name) {
   return db('types')
    .insert({type_name: input_type_name})
}

// Combine the count & insert - the real goal
//
function addTypeNameRec(input_type_name) {

   return countTypeNameRec(input_type_name)
     .then((rec_count) => {
        if (rec_count===0) {
            insertTypeNameRec(input_type_name) 
        } else {
            // we can return an already exists error from here
        }
     })
}

// Web routing code
//
router.post('/additem', function(req, res, next){

   const input_type_name = req.body.getypename;
   // we could validate our input here

   // for simplistic second method - call insertTypeNameRec() here instead
   return addTypeNameRec(input_type_name)
      .then(()=>{
            res.redirect('/additem?success=1')
       })
       .catch((err)=>{ 
            res.redirect('/additem?'+err) 
       })
})

// disclaimer: this code has not been tested

免费赠品(即对您没有询问的事情的评论)......我倾向于尝试将我的能力分成最小的部分/功能。然后对每个部件进行故障排除和测试变得超级简单。我特别尝试在数据库和通信层分离代码。然后很容易将 Web 请求存根,并将它们与其他服务器处理分开测试。


推荐阅读