sql server用xml解析in列表需防内存泄漏和路径硬编码,超2000项应改用临时表;sql server 2016+须用openjson而非string_split处理json;postgresql推荐variadic参数配合= any();mysql 8.0用json_contains需注意类型匹配与索引失效。

SQL Server里用XML参数解析IN列表的实操要点
SQL Server原生不支持把数组直接当参数传进存储过程,IN子句里的值必须展开成逗号分隔的字面量。用XML是较稳妥的老办法,尤其在SQL Server 2005+环境里。
关键不是“能不能”,而是“怎么避免XML节点解析出错或性能掉坑里”。常见错误是直接用sp_xml_preparedocument但没配EXEC sp_xml_removedocument,导致内存泄漏;或者用/root/item这种硬编码路径,结果XML结构稍变就返回空。
- XML参数声明为
@xmlData XML,别用VARCHAR再转,会丢格式或引发编码问题 - 解析时用
OPENXML配合WITH子句显式定义字段类型,比如id INT '@id',避免隐式转换失败 - 若IN列表超2000项,别用XML——节点数过多会让
OPENXML变慢,改用临时表+INSERT ... SELECT分批加载
DECLARE @hdoc INT; EXEC sp_xml_preparedocument @hdoc OUTPUT, @xmlData; SELECT id FROM OPENXML(@hdoc, '/root/item', 2) WITH (id INT '@id');
SQL Server 2016+用STRING_SPLIT处理JSON字符串的限制
很多人看到STRING_SPLIT就以为能直接喂JSON数组,比如'["a","b","c"]'——不行。STRING_SPLIT只认纯逗号分隔字符串,对JSON的引号、方括号、转义字符完全无感,直接传会把整个JSON当一个值切出来。
真要用JSON,得先用OPENJSON(SQL Server 2016起),但它要求输入是合法JSON文本,且默认只解析第一层。常见翻车点:JSON里混了null或数字,而WITH子句没设对应类型,结果字段全为NULL。
- JSON字符串必须用
NVARCHAR(MAX)传入,VARCHAR会导致中文乱码或解析中断 -
OPENJSON(@json, '$')里的路径要写清楚,'$'是根,'$.items'才是嵌套数组 - 如果JSON数组元素是对象(如
[{"id":1},{"id":2}]),WITH必须声明id INT '$.id',不能只写id INT
SELECT value FROM OPENJSON(@json) WITH (value NVARCHAR(100) '$');
PostgreSQL用VARIADIC参数替代IN的更简方案
PostgreSQL其实不用XML或JSON绕弯——它原生支持VARIADIC数组参数,直接让存储过程接收TEXT[]或INT[],然后用= ANY()替代IN,既安全又快。
DMap GL地图JSAPI(dmapgl)开发指南。用于编写、审查、调试 DMap 地图 API 代码,涵盖地图初始化、覆盖物渲染、图层管理、事件处理、控件交互等任务。当用户提及 dmap、dmapgl、jsapi‑gl 或相关地图开发需求时自动触发。
容易被忽略的是:调用时必须显式加VARIADIC关键字,否则PostgreSQL会报“function expects array, got text”。另外,空数组{}传进去,= ANY()会永远返回false,得单独判空处理。
- 函数定义里写
my_func(VARIADIC ids INT[]),不是ids INT[] - 调用时写
SELECT my_func(VARIADIC ARRAY[1,2,3]);,漏掉VARIADIC就报错 - WHERE条件写成
WHERE column = ANY($1),别用IN (SELECT UNNEST($1))——后者多一层计划开销
MySQL 8.0用JSON_CONTAINS做IN等价查询的陷阱
MySQL没原生数组参数,但8.0+的JSON_CONTAINS可以模拟IN行为,前提是目标字段是标量(比如user_id),且JSON数组里全是同类型值。最常踩的坑是:把字符串ID写成"1"(带引号),而数据库字段是INT,导致类型不匹配,JSON_CONTAINS始终返回0。
另一个问题是性能——JSON_CONTAINS无法走索引,大数据量下比拆成OR还慢。如果数组长度固定且较短(≤10),不如拼成WHERE id = ? OR id = ? OR ...。
- JSON数组必须用
JSON_ARRAY()构造,别手拼字符串,避免引号/转义错误 - 比较时用
CAST(json_unquote(JSON_EXTRACT(...)) AS UNSIGNED)确保类型一致 - 若数组来自应用层,优先用
JSON_VALID()校验再进查询,否则JSON_CONTAINS直接报错中断
动态IN这事,核心不在“怎么传”,而在“传完怎么安全展开”——XML要防节点爆炸,JSON要防类型失配,而原生数组支持的语言(如PG)反而最容易忽略调用语法细节。










