【问题标题】:Email Addresses as Table Names, How to Use Prepared / "Safe" Statements?电子邮件地址作为表名,如何使用准备好的/“安全”语句?
【发布时间】:2016-08-09 05:38:21
【问题描述】:

(在此处插入通常的“我没有很多 SQL 经验”。)

我有一个负责发送大量电子邮件的系统,并且我正在添加功能来保存每封电子邮件的记录,并按收件人隔离。

现在我正在设置它,以便这些电子邮件日志将插入一个表格,其中他们的电子邮件是表格名称。但是现在,Node.js 的 pg 库似乎不允许在准备好的语句中使用表名。

我的问题有两个,a) 当我的名字将基于电子邮件地址时,我是否应该担心注入? b) 如果是这样,我该如何解决这里的安全问题?

我目前的处理方式示例:

function _upsertTable(email, cb) {
  // Normalize email address.
  var tableName = 'email."' + email.toLowerCase() + '"';

  client.query([
    ("CREATE TABLE IF NOT EXISTS " + tableName),
      "(",
        "htmlMessage text,",
        "textMessage text,",
        "templateId character(24),",
        "files oid",
      ")"
  ].join(' '), cb);
}

// Insert email record into table
function _recordEmail(email, cb) {
  var tableName = 'email."' + email.toLowerCase() + '"';

  client.query([
    'INSERT INTO ' + tableName,
    'VALUES (',
      '$1,',
      '$2,',
      '$3,',
      'null',
    ')'
  ].join(' '), [html, text, templateId], cb);
}

编辑:

我想指出,回想起来这是一个可怕的想法,并敦促其他人在考虑这样做时不要采取这种方法。请阅读 cmets 以了解为什么这是一个坏主意。

【问题讨论】:

  • 如果您真的要以电子邮件地址命名表,那么您应该立即停止正在做的事情并学习数据建模。我听说过《为凡人设计数据库》这本书的好消息。
  • @DanBracuk 所以我应该停下手头的工作去读一本超过 600 页的书吗?我看不出这是一个有用的评论,因为这与提出的问题没有任何关系,也没有为未来的读者提供任何有用的东西。
  • @Dropped.on.Caprica :您不需要阅读 600 多页的书;只有少数 3 行 cmets。我再说一遍 Dan Bracuk:使用电子邮件作为表名是一个非常糟糕的主意。在您的情况下:您将如何检索使用相同模板(_id)的所有用户或他们引用的文件?也许您必须在一个查询中使用数千个表(涉及目录)。在 ... 再次 ... :动态 SQL。
  • @wildplasser 哦,在对这个主题进行一些思考之后相信我,这是一个可怕的想法,,你提出了非常有效的观点。我只是不认为说“读一本书”真的是一个很好的评论,特别是如果逻辑线被几个例子驳斥了为什么它不是最理想的。

标签: sql node.js postgresql


【解决方案1】:

准备好的语句参数替换通常只适用于语句的数据部分,而不适用于引用 SQL 模式对象的地方。

您可以通过足够的转义和引用自行构建它,但我建议您不要这样做。

恢复您描述的数据的更好方法是在一个表中,其中电子邮件地址为一列。可能将电子邮件地址分隔到一个单独的表中,并通过整数 ID 指向它们以节省一些空间。

【讨论】:

  • 是的,我觉得好像没有办法准备声明,那么我可能走错了路。我将采用更基本的方法来保存这些,可能会将所有电子邮件历史记录存储在一个表中。
猜你喜欢
  • 2014-12-19
  • 1970-01-01
  • 1970-01-01
  • 2011-10-21
  • 2011-01-13
  • 2013-12-25
  • 1970-01-01
  • 1970-01-01
  • 2010-11-21
相关资源
最近更新 更多