laf/packages/database-proxy/docs/convert-sql.md

2.6 KiB
Raw Blame History

Mongo 查询语法转 SQL 的分析

case 1

query = {}
// where 1=1

case 2

query = { id: 0}
// where 1=1 and id = 0

case 3

query = { id: 0, name: "abc"}
// where 1=1 and id = 0 and name = "abc"

case 4

query = {
  id: 0,
  f1: {
    f2: 0
  }
}
// Error不支持此种嵌套属性

case 5

query = {
  f1: 0, 
  f2: {
    $ne: 0
  },
  f3: {
    $in: [1, 2, 3]
  }
}

// where 1=1 and f1 = 0 and f2 <> 0 and f3 in (1, 2, 3)

case 6

query = {
  f1: 0,
  $and: [
    {
      f2: { $gt: 0 }
    },
    {
      f2: { $lt: 1 }
    }
  ]
}

// where 1=1 and f1 = 0 and (f2 > 0 and f2 < 1)

case 7

query = {
  f1: 0,
  $or: [
    {
      f2: { $gt: 0 }
    },
    {
      f2: { $lt: 1 }
    }
  ]
}

// where 1=1 and f1 = 0 and (f2 > 0 or f2 < 1)

case 8

query = {
  f1: 0,
  '$or': [
    { f2: 1},
    { f6: { '$lt': 4000 } },
    {
      '$and': [ { f6: { '$gt': 6000 } }, { f6: { '$lt': 8000 } } ]
    }
  ]
}

// where 1=1 and f1 = 0 and (f2 = 1 or f6 < 4000 or (f6 > 6000 and f6 < 8000))

case 9

query = {
  f1: 0,
  f2: {
    $like: '%keyword%'
  }
}

// where 1=1 and f1 = 0 and f2 like "%keyword%"

Mongo 更新语法转 SQL 的分析

case 1

data = {
  $set: {
    f1: 0,
    f2: 1
  }
}

// update xxx set f1 = 0, f2 = 1 where 1=1

case 2

// 此种语法对应的是 less-api-client-js 的 `set` 方法会覆盖整个文档Mysql 并不支持此种写法
data = {
  f1: 0,
  f2: 1
}

// 遇到此种写法,应直接报错 或者 生成 update xxx set f1 = 0, f2 = 1 where 1=1 兼容执行

case 3

data = {
  '$set': { name: "abc" },
  '$inc': { upvote: 1 },
}

// update xxx set name = "abc", upvote = upvote + 1 where 1=1

case 4

data = {
  $set: { f1: 0}, 
  '$unset': { f2: '' }
}

// ErrorMySQL不支持 $unset 操作,可直接报错 或者 生成 set f2 = null 兼容执行
// 建议客户端使用 $set: { f1: 0, f2: null} 方式代替 $unset
// 其它操作如 $push $pop $shift $unshift 数组操作同理,不支持且不兼容

注意事项

参数化防注入

生成的 sql 应该满足参数化要求,以防止 SQL 注入, 上面生成的 SQL 示例并不是参数化版的。

-- 非参数化版
where 1=1 and id = 0 and name = "abc"

-- 参数化版 SQL
where 1=1 and id = ? and name = ?

-- values
values = [0, "abc"]

使用条件与限制

  1. 不允许嵌套属性查询
  2. 暂不支持 like [已支持]
  3. 暂不支持 联表查询
  4. 暂不支持事务