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) | 将小写字符数据转换为大写后返回字符表达式。 |