string_escape仅负责json字符串内容转义,不加外层双引号、不处理null或非字符串类型,需配合isnull和手动添加引号才能安全拼接合法json。

STRING_ESCAPE 不能直接用于 JSON 字符串拼接
很多人以为 STRING_ESCAPE 是给 JSON 字段“加引号+转义”的万能函数,实际不是。它只做单向转义,不加外层双引号,也不处理 NULL 或非字符串类型——直接套用会导致 JSON 格式错误或 SQL 报错。
典型错误场景:把用户输入的昵称 "O'Reilly & Co." 用 STRING_ESCAPE(value, 'json') 转成 O'Reilly & Co.,然后拼进 JSON 字符串:'{"name":"' + STRING_ESCAPE(@name, 'json') + '"}' → 得到 {"name":"O'Reilly & Co."},这不是合法 JSON(' 和 & 是 HTML 实体,不是 JSON 转义)。
-
STRING_ESCAPE输出的是 JSON 兼容的字符串内容(如把"→",换行 →),但不包双引号 - 必须手动补上外层双引号,且确保输入是
varchar/nvarchar类型;传入NULL会返回NULL,需提前处理 - SQL Server 2016+ 才支持,旧版本会报
Invalid function name 'STRING_ESCAPE'
正确拼 JSON 的三步法:转义 + 引号 + ISNULL
安全拼接 JSON 字段的核心是:先转义内容,再加双引号,最后兜底 NULL。漏掉任何一步都可能破坏 JSON 结构或引发解析失败。
比如构造用户信息 JSON:
SELECT
'{' +
'"name":"' + ISNULL(STRING_ESCAPE(ISNULL(@name, ''), 'json'), '') + '"' +
',' +
'"city":"' + ISNULL(STRING_ESCAPE(ISNULL(@city, ''), 'json'), '') + '"' +
'}' AS json_fragment
-
ISNULL(@name, '')防止STRING_ESCAPE(NULL, 'json')返回NULL,导致整个表达式为NULL -
STRING_ESCAPE(..., 'json')只处理字符串内部特殊字符("、、控制字符等),不碰引号本身 - 外层双引号必须手写,且不能用
STRING_ESCAPE套两层——那会把引号也转成",再加引号就变成""",非法
比 STRING_ESCAPE 更稳的方式:用 FOR JSON AUTO 或 PATH
手工拼 JSON 容易出错,尤其字段多、嵌套深时。FOR JSON 是 SQL Server 原生方案,自动处理转义、类型映射、NULL 表示(默认省略,可用 INCLUDE_NULL_VALUES 控制),还支持数组和嵌套对象。
例如从表生成 JSON:
SELECT id, name, email FROM users WHERE id = 123 FOR JSON PATH, WITHOUT_ARRAY_WRAPPER
- 输出自动是
{"id":123,"name":"O'Reilly","email":"a@b.c"}—— 单引号不用管,"和全自动转义 -
PATH模式允许自定义键名(如name AS 'user.name'),AUTO按 SELECT 列顺序推导结构 - 性能上,
FOR JSON比字符串拼接快,尤其大数据量;但无法在复杂表达式里局部调用,得整条查询重构
常见报错和绕过方法
遇到 String or binary data would be truncated 或 JSON text is not properly formatted?大概率是没控制好长度或混用了转义方式。
-
STRING_ESCAPE输出长度可能比原字符串长(如一个"变成"),如果目标列是varchar(50),而原始值 48 字符含 3 个引号,转义后就 51 字符 → 截断。建议输出列用varchar(max)或提前LEN()校验 - 别把
STRING_ESCAPE和REPLACE混用,比如先REPLACE(@s, '"', '"')再STRING_ESCAPE→ 重复转义,出现\" - 中文字符、emoji 在
STRING_ESCAPE下正常(UTF-16 编码下直接保留),但若客户端解析 JSON 时用错编码(如 GBK),会显示乱码——问题不在转义,在传输层
真正麻烦的不是怎么转义,而是确认 JSON 最终由谁消费:SQL Server 自己解析?前端 JS?还是中间 API?不同消费者对空白、NULL、编码容忍度不同,得按下游定规则。











