← 中文资源

简体中文版本

安全地引用 SQL 标识符

为 PostgreSQL 或 MySQL 引用表名和列名,双写内部引号并拒绝空名称与包含 NUL 的名称。

阅读英文原文

功能说明

SQL 标识符不能像值一样用参数占位符绑定,直接拼接又可能引入注入风险。该函数针对 PostgreSQL 和 MySQL 转义标识符中的引号,并拒绝空名称与 NUL 字符,降低拼接风险。它适合动态表名、排序字段和多租户 schema 等必须拼接标识符的场景。

关键代码

根据 dialect 选择双引号或反引号,先把标识符内部的同类引号双写,再用对应引号包裹。空字符串、非字符串和包含 NUL 的名称直接抛错。qualifyTable 分别引用 schema 与表名后用点连接,保证两段都经过相同校验与转义。

const quote = dialect === "mysql" ? "`" : '"';
return quote + identifier.split(quote).join(quote + quote) + quote;

使用注意

该函数只处理标识符,不能用于字面量或 SQL 片段;值仍应使用参数绑定。调用方必须用白名单校验表名和列名,不能仅依赖转义。不同数据库对大小写折叠规则不同,引用后会保留大小写。NUL 字符在多数驱动中会被截断,因此直接拒绝。未知 dialect 抛 RangeError。

验证方式

断言 quoteIdentifier(‘user“data’) 返回双引号包裹且内部引号双写的结果。MySQL 模式下反引号被双写。空字符串与含 NUL 的名称抛 RangeError。qualifyTable(“public”, “users”) 返回 “public”.“users”。未知 dialect 抛 RangeError,非字符串名称抛 TypeError。