ArcGIS Server 中包含一个安全选项,可强制开发人员在通过 REST 或 SOAP 使用地图、要素、影像和 WFS 服务时使用标准化 SQL 查询。此选项使开发人员和应用程序查询 ArcGIS Server 服务更为简便,并有助于防止 SQL 注入攻击。默认情况下强制使用标准化查询,但是服务器管理员可以禁用标准化查询。
关于标准化查询
启用标准化查询后,ArcGIS Server 将检查标准语法,并且不支持数据库特定的函数和语法。如果您是一名应用程序开发人员,并且正在使用数据库特定函数和语法,则需要更新应用程序代码中的 where 子句以使用 ArcGIS 所支持的常规 SQL 语法。此外,还可以禁止 ArcGIS Server 检查标准化查询。
标准化查询限制
标准化查询会应用于整个 ArcGIS Server 站点;不会只对某些服务启用而对其他服务禁用标准化查询。
不同工作空间之间的连接不支持标准化查询。此外,也不支持通过 OLE DB 连接文件访问的数据库表。如果服务数据包含这些源,则需要使用替代方法来引用数据。
不支持子查询作为 where 子句,如 POP_2010 = (SELECT min(POP_2010) FROM counties。
如何编写标准化查询?
本主题末尾的表格介绍了 ArcGIS Server 所支持的 SQL 函数。此表格能够帮助您了解哪些 SQL 函数可用于生成标准化查询,这些标准化查询可用于应用程序中的地图、要素、影像以及 WFS 服务。
如何知道 ArcGIS Server 是否正在使用标准化查询?
如上所述,标准化查询为默认启用并应用于 ArcGIS Server 站点中的所有地图、要素、影像以及 WFS 服务。但是,服务器管理员可通过登录到 ArcGIS Server Administrator Directory 并浏览至系统 > 属性 > 更新,来验证正在使用的标准化查询。如果系统属性对话框未显示系统属性或显示 {"standardizedQueries": "true"},则标准化查询处于开启状态。
除此之外,管理员、应用程序开发人员和客户可通过使用 ArcGIS Server 服务目录访问服务并查看使用标准化查询属性,来验证是否正在使用标准化查询。对于地图、要素和 WFS 服务,可通过访问服务中的特定图层或表来查看此属性,例如,https://gisserver.domain.com:6443/arcgis/rest/services/folder/service/service type/0。对于影像服务,可在服务端点找到此属性,例如以下端点:https://gisserver.domain.com:6443/arcgis/rest/services/folder/service/ImageServer。
有关如何访问管理员目录的说明或了解如何禁用标准化查询的信息,请参阅该主题的下一部分。
禁用标准化查询
如果需要在应用程序中使用数据库特定的 where 子句语句,可以通过访问 ArcGIS Server 管理员目录禁用标准化查询。要执行此操作,请遵循以下说明。
警告:
禁用此安全选项,您的站点更易受到 SQL 注入攻击。
注:
ArcGIS Enterprise 中的托管要素服务不支持禁用标准化查询。
- 打开管理员目录,然后以具有管理权限的用户身份登录到站点。Administrator Directory 通常位于 https://gisserver.domain.com:6443/arcgis/admin。
- 单击系统 > 属性 > 更新。
- 在操作 - 更新 页面,在系统属性对话框中输入以下字符串:
{"standardizedQueries": "false"} - 单击更新。
- 重新启动 ArcGIS Server。
现在您的站点已配置为允许用户使用非标准化查询向地图、要素、影像以及 WFS 服务发送请求。要重新启用标准化查询,请重复执行以上说明并将 standardizedQueries 属性设置为true。
ArcGIS Server 中支持的 SQL 函数
下面的列表显示了 ArcGIS Server 支持的 SQL 函数以及每个 SQL 函数的语法。在您的应用程序中使用下列函数和语法时,ArcGIS Server 会对其进行转换,使其符合服务使用的数据库规范。
这些函数适用于 ArcGIS Server web 服务,而不适用于托管 web 图层。
| 函数类型 | 函数 | 描述 | 示例 | 备注 |
|---|---|---|---|---|
日期 | CURRENT_DATE | 返回会话时区的当前日期。 | Datefield < CURRENT_DATE | 仅支持下列日期和时间戳语法: 日期 'yyyy-mm-dd',例如 Datefield = date '2012-05-29' timestamp 'yyyy-mm-dd hh:mm:ss',例如,Datefield = timestamp '2012-05-29 15:14:25' |
CURRENT_TIMESTAMP | 返回当前本地时间。 | Timestampfield < CURRENT_TIMESTAMP | ||
EXTRACT(extract_field FROM extract_source) | 返回日期/时间的单个部分,例如,年、月、日、小时、分钟等。 extract_field 参数可以是下列任一关键字:YEAR、MONTH、DAY、HOUR、MINUTE 或 SECOND。 | 搜索十一月的所有行: EXTRACT(MONTH FROM Datefield) = 11 | ||
数学分析 | ABS(numeric_exp) | 返回指定的数值表达式的绝对(正)值。 | ||
CEILING(numeric_exp) | 返回大于或等于指定的数值表达式的最小整数。 | |||
FLOOR(numeric_exp) | 返回小于或等于指定的数值表达式的最大整数。 | |||
LOG(float_exp) | 返回指定的浮点表达式的自然对数。 | |||
LOG10(float_exp) | 返回指定的浮点表达式的以 10 为底的对数。 | |||
POWER(numeric_exp, integer_exp) | 返回指定幂值的指定表达式的值。 | POWER(Numericfield, 2) = 16 | ||
ROUND(numeric_exp, integer_exp) | 返回数值,四舍五入到指定长度或指定精度。 | |||
TRUNCATE(numeric_exp, integer_exp) | 返回数值,而不将值四舍五入到指定长度或指定精度。 | |||
字符串 | CHAR_LENGTH(string_exp) | 返回输入字符串的字符长度。 | ||
CONCAT(string_exp1, string_exp2) | 返回连接两个或多个字符串值后得到的字符串。 | |||
LOWER(string_exp) | 将大写字符数据转换为小写后返回字符表达式。 | |||
SUBSTRING(string_exp FROM start FOR length) | 返回字符或文本表达式的一部分。 | 搜索字符串字段中值的前两个字符为 Ch 的所有行: SUBSTRING(Stringfield FROM 1 FOR 2)='Ch' | ||
UPPER(string_exp) | 将小写字符数据转换为大写后返回字符表达式。 |