SEARCH_IP¶
从一个或多个表中搜索指定字符串列中的有效 IPv4 地址,包括 VARIANT、OBJECT 和 ARRAY 列中的字段。搜索基于单个 IP 地址或您指定的 IP 地址范围。如果此 IP 地址匹配指定列或字段中的 IP 地址,函数将返回 TRUE。
有关使用此函数的更多信息,请参阅 使用全文搜索。
语法¶
SEARCH_IP( <search_data>, <search_string> )
实参¶
search_data
您要搜索的数据,以字符串字面量、列名或到 VARIANT 列中字段的 路径 的逗号分隔的列表表示。搜索数据也可以是一个单一的字面量字符串,这在测试函数时可能很有用。
您可以指定通配符字符 (
*
),其中*
扩展为函数范围内所有表中所有符合条件的列。符合条件的列是那些具有 VARCHAR(文本)、VARIANT、ARRAY 和 OBJECT 数据类型的列。VARIANT、ARRAY 和 OBJECT 数据已转换为文本以便搜索。您还可以使用 ILIKE 和 EXCLUDE 关键字进行筛选。有关该实参的更多信息,请参阅 SEARCH 函数的
search_data
描述。search_string
VARCHAR 字符串包含以下内容之一:
标准 IPv4 格式的完整有效 IP 地址,如
192.0.2.1
。标准 IPv4 格式的有效 IP 地址,其中包含无类域间路由 (CIDR) 范围,如
192.0.2.1/24
。标准 IPv4 格式的有效 IP 地址,其中包含前导零,如
192.000.002.001``(而不是 ``192.0.2.1
)。该函数最多接受 IP 地址每个部分的三位数字。
该实参必须是字面量字符串。指定一对单引号将字符串放在引号里。
不支持以下类型的实参:
列名称
空字符串
多个 IP 地址
部分 IPv4 地址
IPv6 地址
返回¶
返回 BOOLEAN。
如果在
search_string
中指定了有效的 IP 地址,并且在search_data
中找到了匹配的 IP 地址,则返回 TRUE。如果在
search_string
中指定了范围为 CIDR 的有效 IP 地址,并且在search_data
中找到了指定范围内的 IP 地址,则返回 TRUE。如果任一实参为 NULL,则返回 NULL。
否则返回 FALSE。
使用说明¶
SEARCH_IP 函数仅针对 VARCHAR、VARIANT、ARRAY 和 OBJECT 数据执行操作。如果
search_data
实参不包含这些数据类型的数据,则该函数会返回错误。当search_data
实参同时包含支持的数据类型和不支持的数据类型时,函数会搜索支持的数据类型的数据,并静默忽略不支持的数据类型的数据。有关示例,请参阅 预期错误案例的示例。如果
search_string
实参不是有效的 IP 地址,则该函数将返回错误。有关示例,请参阅 预期错误案例的示例。您可以使用指定 ENTITY_ANALYZER 的 ALTER TABLE 命令在作为 SEARCH_IP 函数调用目标的列上添加 FULL_TEXT 搜索优化。例如:
ALTER TABLE ipt ADD SEARCH OPTIMIZATION ON FULL_TEXT( ip1, ANALYZER => 'ENTITY_ANALYZER');
ENTITY_ANALYZER 仅识别实体(例如,IP 地址)。因此,搜索访问路径通常比使用不同分析器的 FULL_TEXT 搜索优化要小得多。
有关更多信息,请参阅 启用 FULL_TEXT 搜索优化。
示例¶
以下示例使用 SEARCH_IP 函数:
在 VARCHAR 列中搜索匹配的 IP 地址¶
以下示例展示了如何使用 SEARCH_IP 函数查询 VARCHAR 列。
创建名为 ipt
的表,并插入两行:
CREATE OR REPLACE TABLE ipt(id INT, ip1 VARCHAR(20), ip2 VARCHAR(20));
INSERT INTO ipt VALUES(1, '192.0.2.146', '203.0.113.5');
INSERT INTO ipt VALUES(2, '192.0.2.111', '192.000.002.146');
运行以下搜索查询。第一个查询使用 SELECT 列表中的 SEARCH_IP 函数,并搜索表中的两个 VARCHAR 列:
SELECT ip1,
ip2,
SEARCH_IP((ip1, ip2), '192.0.2.146')
FROM ipt
ORDER BY ip1;
+-------------+-----------------+--------------------------------------+
| IP1 | IP2 | SEARCH_IP((IP1, IP2), '192.0.2.146') |
|-------------+-----------------+--------------------------------------|
| 192.0.2.111 | 192.000.002.146 | True |
| 192.0.2.146 | 203.0.113.5 | True |
+-------------+-----------------+--------------------------------------+
请注意,尽管 192.000.002.146
有前导零,但 search_data
192.000.002.146
是 search_string
192.0.2.146
的匹配项。
该查询显示了范围为 CIDR 的 search_string
:
SELECT ip1,
ip2,
SEARCH_IP((ip1, ip2), '192.0.2.1/20')
FROM ipt
ORDER BY ip1;
+-------------+-----------------+---------------------------------------+
| IP1 | IP2 | SEARCH_IP((IP1, IP2), '192.0.2.1/20') |
|-------------+-----------------+---------------------------------------|
| 192.0.2.111 | 192.000.002.146 | True |
| 192.0.2.146 | 203.0.113.5 | True |
+-------------+-----------------+---------------------------------------+
该查询显示了带有前导零的 search_string
,对于省略前导零的 IP 地址,则返回 True
:
SELECT ip1,
ip2,
SEARCH_IP((ip1, ip2), '203.000.113.005')
FROM ipt
ORDER BY ip1;
+-------------+-----------------+------------------------------------------+
| IP1 | IP2 | SEARCH_IP((IP1, IP2), '203.000.113.005') |
|-------------+-----------------+------------------------------------------|
| 192.0.2.111 | 192.000.002.146 | False |
| 192.0.2.146 | 203.0.113.5 | True |
+-------------+-----------------+------------------------------------------+
该查询使用 WHERE 子句中的函数,仅搜索 ip2
列。
SELECT ip1,
ip2
FROM ipt
WHERE SEARCH_IP(ip2, '203.0.113.5')
ORDER BY ip1;
+-------------+-------------+
| IP1 | IP2 |
|-------------+-------------|
| 192.0.2.146 | 203.0.113.5 |
+-------------+-------------+
在 WHERE 子句中使用该函数时,如果没有匹配项,则不会返回任何值。
SELECT ip1,
ip2
FROM ipt
WHERE SEARCH_IP(ip2, '203.0.113.1')
ORDER BY ip1;
+-----+-----+
| IP1 | IP2 |
|-----+-----|
+-----+-----+
您可以将 *
字符(或 table.*
)用作 SEARCH 函数的第一个实参,如本示例所示。搜索会对所选表格中所有符合条件的列进行操作。
SELECT ip1,
ip2
FROM ipt
WHERE SEARCH_IP((*), '203.0.113.5')
ORDER BY ip1;
+-------------+-------------+
| IP1 | IP2 |
|-------------+-------------|
| 192.0.2.146 | 203.0.113.5 |
+-------------+-------------+
您还可以使用 ILIKE 和 EXCLUDE 关键字进行筛选。有关这些关键字的更多信息,请参阅 SELECT。
该搜索使用 ILIKE 关键字,仅在以字符串 ip
开头的列中进行搜索。
SELECT ip1,
ip2
FROM ipt
WHERE SEARCH_IP(* ILIKE 'ip%', '192.0.2.111')
ORDER BY ip1;
+-------------+-----------------+
| IP1 | IP2 |
|-------------+-----------------|
| 192.0.2.111 | 192.000.002.146 |
+-------------+-----------------+
要 对 ``ipt` 表中的列启用 FULL_TEXT 搜索优化 <label-enable_full_text_search>`,请运行以下 ALTER TABLE 命令:
ALTER TABLE ipt ADD SEARCH OPTIMIZATION ON FULL_TEXT(
ip1,
ip2,
ANALYZER => 'ENTITY_ANALYZER');
备注
您指定的列必须是 VARCHAR 或 VARIANT 列。不支持其他数据类型的列。
在 VARIANT 列中搜索匹配的 IP 地址¶
以下示例展示了如何使用 SEARCH_IP 函数查询 VARIANT 列。
以下示例使用 SEARCH_IP 函数搜索 VARIANT 列中字段的路径。创建名为 iptv
的表,并插入两行:
CREATE OR REPLACE TABLE iptv(ip1 VARIANT);
INSERT INTO iptv(ip1)
SELECT PARSE_JSON(' { "ipv1": "203.0.113.5", "ipv2": "203.0.113.5" } ');
INSERT INTO iptv(ip1)
SELECT PARSE_JSON(' { "ipv1": "192.0.2.146", "ipv2": "203.0.113.5" } ');
运行以下搜索查询。第一个查询仅搜索 ipv1
字段。第二个查询搜索 ipv1
和 ipv2
。
SELECT * FROM iptv
WHERE SEARCH_IP((ip1:"ipv1"), '203.0.113.5');
+--------------------------+
| IP1 |
|--------------------------|
| { |
| "ipv1": "203.0.113.5", |
| "ipv2": "203.0.113.5" |
| } |
+--------------------------+
SELECT * FROM iptv
WHERE SEARCH_IP((ip1:"ipv1",ip1:"ipv2"), '203.0.113.5');
+--------------------------+
| IP1 |
|--------------------------|
| { |
| "ipv1": "203.0.113.5", |
| "ipv2": "203.0.113.5" |
| } |
| { |
| "ipv1": "192.0.2.146", |
| "ipv2": "203.0.113.5" |
| } |
+--------------------------+
要 对 ``ip1` VARIANT 列及其字段启用 FULL_TEXT 搜索优化 <label-enable_full_text_search>`,请运行以下 ALTER TABLE 命令:
ALTER TABLE iptv ADD SEARCH OPTIMIZATION ON FULL_TEXT(
ip1:"ipv1",
ip1:"ipv2",
ANALYZER => 'ENTITY_ANALYZER');
备注
您指定的列必须是 VARCHAR 或 VARIANT 列。不支持其他数据类型的列。
在文本的长字符串中搜索匹配的 IP 地址¶
创建名为 ipt_log
的表,并插入行:
CREATE OR REPLACE TABLE ipt_log(id INT, ip_request_log VARCHAR(200));
INSERT INTO ipt_log VALUES(1, 'Connection from IP address 192.0.2.146 succeeded.');
INSERT INTO ipt_log VALUES(2, 'Connection from IP address 203.0.113.5 failed.');
INSERT INTO ipt_log VALUES(3, 'Connection from IP address 192.0.2.146 dropped.');
在包含 192.0.2.146
IP 地址的 ip_request_log
列中搜索日志条目:
SELECT * FROM ipt_log
WHERE SEARCH_IP(ip_request_log, '192.0.2.146')
ORDER BY id;
+----+---------------------------------------------------+
| ID | IP_REQUEST_LOG |
|----+---------------------------------------------------|
| 1 | Connection from IP address 192.0.2.146 succeeded. |
| 3 | Connection from IP address 192.0.2.146 dropped. |
+----+---------------------------------------------------+
预期错误案例的示例¶
以下示例显示了返回预期语法错误的查询。
此示例失败了,因为 5
不是 search_string
实参支持的数据类型。
SELECT SEARCH_IP(ip1, 5) FROM ipt;
001045 (22023): SQL compilation error:
argument needs to be a string: '1'
以下示例失败的原因是 search_string
实参不是有效的 IP 地址。
SELECT SEARCH_IP(ip1, '1925.0.2.146') FROM ipt;
000937 (22023): SQL compilation error: error line 1 at position 22
invalid argument for function [SEARCH_IP(IPT.IP1, '1925.0.2.146')] unexpected argument [1925.0.2.146] at position 1,
以下示例失败的原因是 search_string
实参为空字符串。
SELECT SEARCH_IP(ip1, '') FROM ipt;
000937 (22023): SQL compilation error: error line 1 at position 22
invalid argument for function [SEARCH_IP(IPT.IP1, '')] unexpected argument [] at position 1,
此示例失败了,因为不存在为 search_data
实参指定支持的数据类型的列。
SELECT SEARCH_IP(id, '192.0.2.146') FROM ipt;
001173 (22023): SQL compilation error: error line 1 at position 7: Expected non-empty set of columns supporting full-text search.
此示例成功了,因为存在为 search_data
实参指定支持的数据类型的列。该函数忽略了 id
列,因为它不是支持的数据类型
SELECT SEARCH_IP((id, ip1), '192.0.2.146') FROM ipt;
+-------------------------------------+
| SEARCH_IP((ID, IP1), '192.0.2.146') |
|-------------------------------------|
| True |
| False |
+-------------------------------------+