【问题标题】:Parameterize clause optional fields WHERE clause参数化子句可选字段 WHERE 子句
【发布时间】:2022-02-03 18:19:23
【问题描述】:

我有一个带有 Typescript 的 Node JS 项目,其中我在 BigQuery 中包含数据库查询。

该功能是生成一个带有搜索字段和值的 JSON 对象,以将它们传递给查询并返回与这些字段匹配的所有记录。

这是对象:

let dataObj = {
  "host": "192.168,AS101",
  "code": "001,025",
  "country": "Colombia"
}

这是查询:

SELECT *
  FROM TABLE_TEST
  WHERE hostName in ('${dataObj.host}') and codeData in (${dataObj.code}) and countryName in ('${dataObj.country}')

我的问题:对象的所有字段都是可选的,如何在WHERE内添加或删除字段?

示例:

新的 JSON 对象:

let dataObj = {
  "host": "192.168,AS101",
  "country": "Colombia"
}

这是必须执行的查询:

SELECT *
  FROM TABLE_TEST
  WHERE hostName in ('${dataObj.host}') and countryName in ('${dataObj.country}')

升级:

JSON 对象的字段与表的字段名称不同,所以我需要更改它们的名称,这是我目前所做的:

function formatName(key: string) {
  if (key == 'host') {
    return 'hostName'
  } else if (key == 'code') {
    return 'codeData'
  } else if (key == 'country') {
    return 'countryName'
  } else {
    return false
  }
}

let sql = " SELECT * FROM MYTABLE WHERE true ";
Object.entries(dataObj).map(
  (entri) => (sql = `${sql} AND ${formatName(entri[0])} in ("${entri[1]}")`)
);

包含在 where 子句中的每个键的数据不能转到“192.168,AS101”,但必须是“192.168”、“AS101”,这样查询才能正确提取它。这就是我所做的,但查询没有捕捉到它:

let newData = {
  "host": dataObj.host.split(','),
  "code": dataObj.code.split(','),
  "country": dataObj.country.split(',')
}

let sql = " SELECT * FROM MYTABLE WHERE true ";
    Object.entries(dataObj).map(
      (entri) => (sql = `${sql} AND ${entri[0]} in ("${entri[1]}")`)
    );

【问题讨论】:

    标签: node.js json typescript google-bigquery where-clause


    【解决方案1】:

    在这种情况下,我使用了著名的 WHERE 1=1 技巧

    const dataObj = {
        host: "192.168,AS101",
        code: "001,025",
        country: "Colombia",
      };
    
      let sql = " SELECT * FROM MYTABLE WHERE 1=1 ";
      Object.entries(dataObj).map(
        (entri) => (sql = `${sql} AND ${entri[0]} in (${entri[1]})`)
      );
      console.log(sql); <-- SELECT * FROM MYTABLE WHERE 1=1  AND host in (192.168,AS101) AND code in (001,025) AND country in (Colombia)
    
    const dataObj = {
        host: "192.168,AS101",
      };
    
      let sql = " SELECT * FROM MYTABLE WHERE 1=1 ";
      Object.entries(dataObj).map(
        (entri) => (sql = `${sql} AND ${entri[0]} in (${entri[1]})`)
      );
      console.log(sql); <-- SELECT * FROM MYTABLE WHERE 1=1  AND host in (192.168,AS101)
    

    【讨论】:

    • 我通常使用WHEN true。这看起来更自然:o)
    • 是的,两者都很相似
    • 这适用于相同的 JSON 属性,问题是表字段没有相同的名称:host -&gt; hostNamecode -&gt; codeDatacountry -&gt; countryData。有没有办法在哪里更改该名称?
    • 您是说 db 中的列名与您的对象属性不同吗?如果是的话,有很多解决方案可以进行映射:使用列名向对象添加属性,使用映射创建枚举,...
    • 我添加了一个函数formatName(key: string),它包含几个条件,并根据键的值返回一个字符串。在查询中我称之为:${formatName(entri[0]}。我不知道是否有更清洁或更好的方法来做到这一点
    猜你喜欢
    • 1970-01-01
    • 2012-04-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-05
    • 2013-04-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多