[comment]: # translation:outdated

[comment]: # ({36f796e5-dc992d4f})
# 12 利用ODBC SQL查询执行自动发现

[comment]: # ({/36f796e5-dc992d4f})

[comment]: # ({dcf4796a-dcf4796a})
#### 概述

此类低级别[自动发现](/manual/discovery/low_level_discovery) 通过使用SQL查询实现，其结果自动转换成一个匹配低级别自动发现的JSON格式的JSON对象。

[comment]: # ({/dcf4796a-dcf4796a})

[comment]: # ({dd23cfaf-c1ef39b4})
#### 监控项键值

设置监控项类型为 "数据库监控" 来执行SQL查询。
因此，[ODBC监控](/manual/config/items/itemtypes/odbc_checks) 页面中的大部分用法说明，都是为了"数据库监控"类型的自动发现规则能正常执行。

"数据库监控"类型的自动发现规则会用到两个键值:

-   **db.odbc.discovery**\[<唯一简短描述>,<dsn(数据源名称)>,<连接字符串>\] - 此监控项将SQL查询结果转换为一个JSON数组，其中表的字段名称会转换为宏的名称，宏的名称与发现的对应值成对匹配。这些宏可用于创建监控项和触发器等原型。另请参阅: [使用
    db.odbc.discovery](#使用 db.odbc.discovery).

-   **db.odbc.get**\[<唯一简短描述>,<dsn(数据源名称)>,<连接字符串>\] - 此监控项将SQL查询结果转换为一个JSON数组，保留原始表字段名称作为输入框的名称，以JSON格式表示，并与对应的已发现的值成对匹配。相比于
    `db.odbc.discovery[]`, 此监控项不在返回的JSON数组中创建低级别自动发现的宏, 因此无需检查表字段名称是否是有效的宏名称。 根据需要，可以将低级发现宏定义作为附加步骤，针对返回的JSON值，在 [自定义LLD宏](/manual/discovery/low_level_discovery#自定义宏)中使用JSONPath方法。另请参阅: [使用 db.odbc.get](#使用 db.odbc.get).

[comment]: # ({/dd23cfaf-c1ef39b4})

[comment]: # ({0f9c9410-0f9c9410})
#### 使用 db.odbc.discovery

让我们看一个SQL查询转换为JSON数组的真实案例。我们通过在Zabbix数据库上使用ODBC查询对Zabbix proxy执行低级别自动发现。 此功能对于自动创建 "zabbix\[proxy,<name>,lastaccess\]"
[内部监控项](/manual/config/items/itemtypes/internal) 并监控存活的proxy很有用。

下面开始配置自动发现规则：

![lld\_rule\_odbc.png](../../../../../assets/en/manual/discovery/low_level_discovery/lld_rule_odbc.png)

所有强制输入区域均标记为红色星号。

此处Zabbix数据库上的查询用于查询所有Zabbix proxy，连同proxy所监控的主机数量. 比如，主机数量可用于过滤掉没有监控任何主机的proxy：

    mysql> SELECT h1.host, COUNT(h2.host) AS count FROM hosts h1 LEFT JOIN hosts h2 ON h1.hostid = h2.proxy_hostid WHERE h1.status IN (5, 6) GROUP BY h1.host;
    +---------+-------+
    | host    | count |
    +---------+-------+
    | Japan 1 |     5 |
    | Japan 2 |    12 |
    | Latvia  |     3 |
    +---------+-------+
    3 rows in set (0.01 sec)

通过 "db.odbc.discovery\[,{$DSN}\]" 监控项的内部工作机制, 查询结果会自动转换为下面的JSON数组：

``` {.java}
[
    {
        "{#HOST}": "Japan 1",
        "{#COUNT}": "5"
    },
    {
        "{#HOST}": "Japan 2",
        "{#COUNT}": "12"
    },
    {
        "{#HOST}": "Latvia",
        "{#COUNT}": "3"
    }
]
```

可以看到字段名称变为宏的名称, 所选的记录变成这些宏的值。

::: noteclassic
 如果通过这种方式展示字段名称转换为宏名称不是很明显，那建议在上面的例子中使用字段别名，比如
"COUNT(h2.host) AS count"。

如果字段名称无法转换为有效的宏名称，则自动发现规则变为unsupport(不支持的)状态，其错误消息显示不合规字段的编号. 如果需要额外帮助, debug级别DebugLevel=4的Zabbix server日志文件中可找到获取的字段名称：

    $ grep db.odbc.discovery /tmp/zabbix_server.log
     ...
     23876:20150114:153410.856 In db_odbc_discovery() query:'SELECT h1.host, COUNT(h2.host) FROM hosts h1 LEFT JOIN hosts h2 ON h1.hostid = h2.proxy_hostid WHERE h1.status IN (5, 6) GROUP BY h1.host;'
     23876:20150114:153410.860 db_odbc_discovery() column[1]:'host'
     23876:20150114:153410.860 db_odbc_discovery() column[2]:'COUNT(h2.host)'
     23876:20150114:153410.860 End of db_odbc_discovery():NOTSUPPORTED
     23876:20150114:153410.860 Item [Zabbix server:db.odbc.discovery[proxies,{$DSN}]] error: Cannot convert column #2 name to macro.


:::

现在理解了SQL查询如何转换成一个JSON对象后, 可以在监控项原型中使用 {\#HOST} 宏了：

![item\_prototype\_odbc.png](../../../../../assets/en/manual/discovery/low_level_discovery/item_prototype_odbc.png)

一旦自动发现开始执行, 会根据每个proxy创建一个对应的监控项：

![discovered\_items\_odbc1.png](../../../../../assets/en/manual/discovery/low_level_discovery/discovered_items_odbc1.png)

[comment]: # ({/0f9c9410-0f9c9410})

[comment]: # ({43f8549f-43f8549f})
#### 使用 db.odbc.get

请看下面使用 `db.odbc.get[,{$DSN}]` 和相关SQL语句的例子:

    mysql> SELECT h1.host, COUNT(h2.host) AS count FROM hosts h1 LEFT JOIN hosts h2 ON h1.hostid = h2.proxy_hostid WHERE h1.status IN (5, 6) GROUP BY h1.host;
    +---------+-------+
    | host    | count |
    +---------+-------+
    | Japan 1 |     5 |
    | Japan 2 |    12 |
    | Latvia  |     3 |
    +---------+-------+
    3 rows in set (0.01 sec)

会返回这个JSON数组:

``` {.java}
[
    {
        "host": "Japan 1",
        "count": "5"
    },
    {
        "host": "Japan 2",
        "count": "12"
    },
    {
        "host": "Latvia",
        "count": "3"
    }
]
```

可以看到, 返回的JSON数组中不包含低级别自动发现的宏. 然而, 可以在自动发现规则的[LLD 宏](/manual/discovery/low_level_discovery#custom_macros) 选项卡中利用JSONPath来自定义宏, 比如:

    {#HOST} → $.host

现在这个 {\#HOST} 宏可用在监控项原型中了:

![item\_prototype\_odbc.png](../../../../../assets/en/manual/discovery/low_level_discovery/item_prototype_odbc.png)

[comment]: # ({/43f8549f-43f8549f})
