• 技术分享 | MySQL Shell 运行 SQL 的两种内置方法概述


    作者:杨涛涛

    资深数据库专家,专研 MySQL 十余年。擅长 MySQL、PostgreSQL、MongoDB 等开源数据库相关的备份恢复、SQL 调优、监控运维、高可用架构设计等。目前任职于爱可生,为各大运营商及银行金融企业提供 MySQL 相关技术支持、MySQL 相关课程培训等工作。

    本文来源:原创投稿

    *爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源。


    MySQL Shell 是兼容 MySQL 传统命令行客户端的超级替代版,支持 SQL 、JavaScript 、Python 三种语言环境。工具自身包含了很多组件,使得 DBA 们管理 MySQL 更加便捷高效。

    今天我们来介绍 MySQL Shell 的组件:MYSQLX 组件的两个检索函数在具体使用上的一些区别。

    MYSQLX 组件包含很多预置的类库, 其中与MySQL 交互最直接的就是 Session 类库。Session 类库里又包含一系列内置函数来处理数据:其中函数 run_sql 和 sql 都可以直接和 MySQL 服务端交互来运行 SQL 语句。那到底有什么区别呢? 我们接下来具体介绍这两个。(Python 环境写法:run_sql、sql;JavaScript环境下:runSQL、sql)

    第一、函数run_sql 如何使用:

    先连上 X 端口 33060,替代默认语言环境为 Python ,变量 c1 即为 Session 对象(Session:root@localhost:33060)。

    root@ytt-pc-cheap:/home/ytt# mysqlsh mysqlx:/root@localhost:33060/ytt --py
    MySQL Shell 8.0.30
    ...
    Creating an X protocol session to 'root@localhost:33060/ytt'
    Fetching schema names for autocompletion... Press ^C to stop.
    Your MySQL connection id is 9 (X protocol)
    Server version: 8.0.30 MySQL Community Server - GPL
    Default schema `ytt` accessible through db.
    MySQL  localhost:33060+ ssl  ytt  Py > c1=db.get_session()
    MySQL  localhost:33060+ ssl  ytt  Py > c1
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    执行 run_sql 创建表t1: run_sql 可以运行任何 MySQL 兼容的 SQL 语句。

    MySQL  localhost:33060+ ssl  ytt  Py > c1.run_sql("create table t1(id int auto_increment primary key, r1 int)")
    Query OK, 0 rows affected (0.0656 sec)
    MySQL  localhost:33060+ ssl  ytt  Py > c1.run_sql("desc t1")
    +-------+------+------+-----+---------+----------------+
    | Field | Type | Null | Key | Default | Extra          |
    +-------+------+------+-----+---------+----------------+
    | id    | int  | NO   | PRI | NULL    | auto_increment |
    | r1    | int  | YES  |     | NULL    |                |
    +-------+------+------+-----+---------+----------------+
    2 rows in set (0.0017 sec)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    插入几条样例数据:

    MySQL  localhost:33060+ ssl  ytt  Py > c1.run_sql("insert into t1(r1) values (10),(20),(30)")
    Query OK, 3 rows affected (0.0114 sec)
    
    Records: 3  Duplicates: 0  Warnings: 0
    
    • 1
    • 2
    • 3
    • 4

    用 run_sql 来执行 查询语句:

    MySQL  localhost:33060+ ssl  ytt  Py > c1.run_sql("table t1")
    +----+----+
    | id | r1 |
    +----+----+
    |  1 | 10 |
    |  2 | 20 |
    |  3 | 30 |
    +----+----+
    3 rows in set (0.0008 sec)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    以上都是直接运行 run_sql 函数的结果。

    其实 run_sql 函数执行后会返回一个 SqlResult 对象,SqlResult 对象包含很多函数:获取语句执行时间,一次性获取一行或者多行数据,判断是否有数据等等。 既然是 SqlResult ,那就是一个结果集,不支持多次获取,类似 MySQL 的游标。

    接下来把 run_sql 函数执行结果赋予一个变量 r1 ,后续操作都通过 r1 来进行:r1 被赋予 SqlResult 对象。

    MySQL  localhost:33060+ ssl  ytt  Py > r1=c1.run_sql("table t1")
    MySQL  localhost:33060+ ssl  ytt  Py > r1.has_data()
    true
    MySQL  localhost:33060+ ssl  ytt  Py > r1.get_execution_time()
    0.0010 sec
    MySQL  localhost:33060+ ssl  ytt  Py > r1.fetch_one()
    [
        1,
        10
    ]
    MySQL  localhost:33060+ ssl  ytt  Py > r1.fetch_one()
    [
        2,
        20
    ]
    MySQL  localhost:33060+ ssl  ytt  Py > r1.fetch_one()
    [
        3,
        30
    ]
    MySQL  localhost:33060+ ssl  ytt  Py > r1.fetch_one()
    MySQL  localhost:33060+ ssl  ytt  Py >               
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    run_sql 函数也可以绑定变量执行:

    MySQL  localhost:33060+ ssl  ytt  Py > c1.run_sql("select * from t1 where r1 in (?,?,?)",[10,20,30])
    +----+----+
    | id | r1 |
    +----+----+
    |  1 | 10 |
    |  2 | 20 |
    |  3 | 30 |
    +----+----+
    3 rows in set (0.0004 sec)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    第二、函数 sql 如何使用:

    sql 函数和 run_sql 函数不一样,它返回的不是 SqlResult 对象,而是一个 SqlExecute 对象,是 SqlResult 对象产生之前的阶段。举个例子:把 sql 函数执行结果赋予变量 r2 ,这样每调用一次 r2 ,相当于重新执行一次原请求。

    MySQL  localhost:33060+ ssl  ytt  Py > r2=c1.sql("table t1")
    MySQL  localhost:33060+ ssl  ytt  Py > r2
    +----+----+
    | id | r1 |
    +----+----+
    |  1 | 10 |
    |  2 | 20 |
    |  3 | 30 |
    +----+----+
    3 rows in set (0.0004 sec)
    MySQL  localhost:33060+ ssl  ytt  Py > r2
    +----+----+
    | id | r1 |
    +----+----+
    |  1 | 10 |
    |  2 | 20 |
    |  3 | 30 |
    +----+----+
    3 rows in set (0.0002 sec)   
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    如果把变量 r2 的执行结果赋予变量 r3 ,那 r3 就变成一个 SqlResult 对象,只支持获取一次,又回退到 run_sql 函数的结果:

    MySQL  localhost:33060+ ssl  ytt  Py > r3=r2.execute()
    MySQL  localhost:33060+ ssl  ytt  Py > r3.fetch_all()
    [
        [
            1,
            10
        ],
        [
            2,
            20
        ],
        [
            3,
            30
        ]
    ]
    
    MySQL  localhost:33060+ ssl  ytt  Py > r3.fetch_all()
    []      
    MySQL  localhost:33060+ ssl  ytt  Py > r3
    Empty set (0.0004 sec)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    sql 函数同样支持执行绑定变量的请求: 一次绑定一个数组。

    MySQL  localhost:33060+ ssl  ytt  Py > r2=c1.sql("select * from t1 where r1 in (?,?,?)")
    MySQL  localhost:33060+ ssl  ytt  Py > r2.bind([10,20,30])
    +----+----+
    | id | r1 |
    +----+----+
    |  1 | 10 |
    |  2 | 20 |
    |  3 | 30 |
    +----+----+
    3 rows in set (0.0006 sec)
    MySQL  localhost:33060+ ssl  ytt  Py > r2.bind([40,50,30])
    +----+----+
    | id | r1 |
    +----+----+
    |  3 | 30 |
    +----+----+
    1 row in set (0.0002 sec)     
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    结论:

    对于函数 run_sql 和 sql 来讲,可以参考对象 SqlResult 和 SqlExecute 的差异来选择自己最合适的使用场景。
  • 相关阅读:
    Unity之NetCode多人网络游戏联机对战教程(3)--NetworkObject组件讲解
    使用AndroidStudio调试Framework
    Failed to configure a DataSource: ‘url‘ attribute is not specified and no em
    JAVA设计模式 —— 工厂模式
    代码随想录训练营day46, 单词拆分和多重背包
    Go语言内置类型和函数
    【C++】C++11——C++11介绍、初始化列表、声明、auto、decltype、nullptr、范围for循环
    ScheduledExecutorService 接口
    基于Canal实现MySQL 8.0 数据库数据同步
    Python之正则表达式
  • 原文地址:https://blog.csdn.net/ActionTech/article/details/127614036