目录
- 一、先说结论
- 二、测试环境
- 三、能用的写法
- 3.1 比较、模糊、范围
- 3.2 关联字段和明细字段
- 3.3 SQL Server 函数也能用
- 四、三个坑
- 4.1 空文本不是 NULL,是空格
- 4.2 and / or 不加括号,结果会错
- 4.3 FieldKeys 能写表达式,但不能聚合
- 五、不能用的写法
- 5.1 子查询:直接被拦
- 5.2 聚合:count、sum 都不行
- 六、拼 FilterString 的安全写法
- 七、几个常用的过滤写法
- 八、最后
一、先说结论
不能直接写 SQL 语句,但查询接口的过滤条件FilterString基本就是 SQL 的 WHERE 子句。
| 写法 | 能不能用 | 实测 |
|---|---|---|
=、<>、!=、>、>= | 能 | ✔ |
like、in、not in、between ... and | 能 | ✔ |
and、or、括号 | 能,但要注意优先级 | ✔ |
is null、is not null | 能写,但空文本不是 NULL | ✔ |
关联字段FCustomerID.FNumber | 能 | ✔ |
明细字段FMaterialID.FNumber | 能 | ✔ |
SQL Server 函数:GETDATE()、DATEADD()、YEAR()、LEN()、LTRIM()、RTRIM() | 能(测试环境是 SQL Server) | ✔ |
子查询in (select ...) | 不能,被拦截 | ✘ |
在FieldKeys里聚合count()、sum() | 不能,直接报 SQL 错 | ✘ |
下面是逐条实测,报错原文照抄。
二、测试环境
- 金蝶云星空官方公开体验环境,账套「金蝶蓝海实业集团」,用户 demo
- 日期:2026-09-26
- 接口:
DynamicFormService.ExecuteBillQuery,单据:销售出库单SAL_OUTSTOCK - 只调查询接口,没有写入、修改任何数据
请求格式(后面只写FilterString这一段):
{"data":{"FormId":"SAL_OUTSTOCK","FieldKeys":"FBillNo","FilterString":"这里是过滤条件","OrderString":"FBillNo","Limit":5}}三、能用的写法
3.1 比较、模糊、范围
FBillNo='XSCKD000001' → 1 条 FDocumentStatus<>'C' → 正常返回 FDocumentStatus!='C' → 和 <> 结果一样 FBillNo like 'XSCKD00000%' → 正常返回 FBillNo in ('XSCKD000001','XSCKD000002') → 2 条 FDocumentStatus not in ('C') → 正常返回 FDate between '2026-09-01' and '2026-09-30' → 正常返回 FModifyDate>='2026-09-20' → 正常返回,修改时间带时分秒几个细节:
- 字符串用单引号
- 日期直接写成字符串
'2026-09-01'就能比较 - 字段名不区分大小写:
fbillno='XSCKD000001'和FBillNo='XSCKD000001'结果一样 - 字符串里的单引号要写两个:
FNote like '%''%'不报错
3.2 关联字段和明细字段
基础资料字段用点号取它的编码或名称:
FCustomerID.FNumber='CUST0001' → 按客户编码过滤 FCustomerID.FName like '%金蝶%' → 按客户名称模糊查 FMaterialID.FNumber='1.1110001' → 按明细里的物料过滤按明细字段过滤,返回的是包含这个物料的单据。实测FMaterialID.FNumber='1.1110001'返回了XSCKD000001、XSCKD000003两张单。
注意:如果FieldKeys里也带了明细字段,返回会变成一条明细一行,分页时一张单可能被切断。这个坑我在「金蝶云星空 WebAPI 查询和查看接口的区别」那篇里专门写过。
3.3 SQL Server 函数也能用
FDate>=DATEADD(day,-30,GETDATE()) → 最近 30 天,正常返回 year(FDate)=2026 → 正常返回 len(FBillNo)>6 → 正常返回 ltrim(rtrim(FNote))='' → 正常返回这说明FilterString基本是原样拼进 SQL 的 WHERE 里的,数据库能认的函数就能用。
注意:公开体验环境的数据库是 SQL Server(后面报错信息都是 SQL Server 的原文)。金蝶云星空也支持 Oracle,如果客户账套是 Oracle,函数写法不一样,比如GETDATE()在 Oracle 里要换成SYSDATE。Oracle 账套我没测过,用之前先在客户的测试账套试一下。
另外GETDATE()取的是数据库服务器的时间,服务器时区不对的话,「最近 30 天」会差几个小时。做增量同步更稳的写法是把时间点算好,直接写成字符串传进去。
四、三个坑
4.1 空文本不是 NULL,是空格
想查「备注为空」的单据,第一反应是:
FNote is null → 0 条结果一条都没有。换成:
FNote is not null → 正常返回,备注值是 " "(一个空格) FNote=' ' → 正常返回 FNote='' → 正常返回,结果和 FNote=' ' 一样原因:金蝶里没填的文本字段存的是一个空格,不是 NULL。而 SQL Server 比较字符串时会忽略末尾空格,所以''和' '算相等。
查空文本用FNote='',别用is null。
顺带一个现象:公开体验环境里有单据编号就是一个空格" "的出库单,应该是有人暂存了没填单号。做同步时对单号要有空值判断,别拿空格单号去做唯一键。
4.2 and / or 不加括号,结果会错
想要「已审核或审核中,并且单号以 XSCKD 开头」:
FDocumentStatus='C' or FDocumentStatus='B' and FBillNo like 'XSCKD%'实测返回了26091、260912、26093这些不是 XSCKD 开头的单。
因为 SQL 里and优先级比or高,上面这句实际等于:
FDocumentStatus='C' or (FDocumentStatus='B' and FBillNo like 'XSCKD%')加上括号就对了:
(FDocumentStatus='C' or FDocumentStatus='B') and FBillNo like 'XSCKD%'只要同时出现 and 和 or,一律加括号。
4.3 FieldKeys 能写表达式,但不能聚合
FieldKeys里写简单表达式可以:
FieldKeys: "FBillNo,FRealQty*2" 返回:[["XSCKD000001", 4.0000000000]]但想用聚合函数汇总就不行,见下一节。
五、不能用的写法
5.1 子查询:直接被拦
FID in (select FID from T_SAL_OUTSTOCK where FDOCUMENTSTATUS='C')报错原文:
过滤条件不能包含关键字【select】,请重新检查!金蝶在接口层拦了select关键字。不过写在字符串里的 select 不会被误伤:实测FNote like '%select%'正常返回(0 条,没报错)。
5.2 聚合:count、sum 都不行
FieldKeys写count(FID),报错原文:
Column 'T_SAL_OUTSTOCK.FID' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.FieldKeys写sum(FRealQty),报错原文:
Invalid column name 'FRealQty'.两个都是 SQL Server 的原始报错,从第一条还能看出销售出库单表头的物理表名是T_SAL_OUTSTOCK。
结论:查询接口不做汇总。要汇总有两个办法:
- 把明细拉回来,在自己程序里算
- 用金蝶自己的报表,或者让懂 BOS 的人做一张汇总报表
六、拼 FilterString 的安全写法
FilterString是拼进 SQL 的,外部传进来的值别直接拼。虽然金蝶拦了select,但单引号没处理好,轻则报错,重则条件被改写。
最少要做单引号转义:
// 把一个值变成 FilterString 里安全的字符串字面量constsqlStr=v=>"'"+String(v).replace(/'/g,"''")+"'";// 单号来自外部系统constbillNo=order.no;constfilter=`FBillNo=${sqlStr(billNo)}`;// 多个值constlist=ids.map(sqlStr).join(',');constfilter2=`FBillNo in (${list})`;更稳的做法是对外部输入先校验格式:单号只允许字母、数字、横线,不符合的直接拒绝,根本不进FilterString。
七、几个常用的过滤写法
对接里最常用的几种,直接抄:
| 场景 | FilterString |
|---|---|
| 只要已审核的单 | FDocumentStatus='C' |
| 增量同步:上次同步之后改过的 | FModifyDate>='2026-09-26 08:00:00' |
| 某段日期的单 | FDate between '2026-09-01' and '2026-09-30' |
| 按客户编码 | FCustomerID.FNumber='CUST0001' |
| 推单前查重:金蝶里有没有这些单号 | FBillNo in ('A001','A002','A003') |
| 备注为空 | FNote='' |
| 组合条件 | (条件1 or 条件2) and 条件3,一定加括号 |
八、最后
- 金蝶云星空接口支持 SQL 查询吗:不能直接写 SQL,但
FilterString就是 WHERE 子句,大部分写法和 SQL Server 函数都能用 - 不能用:子查询(拦
select)、聚合(count、sum报 SQL 错) - 三个坑:空文本是空格不是 NULL;and/or 要加括号;明细字段会让一单变多行
- 安全:外部输入先校验、单引号转义,别直接拼
上一篇讲了查询接口和查看接口的区别,这一篇是查询接口的过滤条件。在写金蝶对接、被过滤条件卡住的,评论区贴你的 FilterString 和报错,看到都会回。