板凳-------Mysql cookbook学习 (十二--------2)

第10章 元数据 354

10.0 概述 354

10.1 获取受语句影响的行数 356

10.2 获取结果集的元数据 359

10.3 确认语句是否会生成结果集 369

10.4 使用元数据来格式化查询输出 369

10.5 查看数据库和表或检查其存在性 373

sql 复制代码
mysql> update profile set cats = 0 where cats = 0;
Query OK, 0 rows affected (0.03 sec)
Rows matched: 2  Changed: 0  Warnings: 0

mysql> select id, name, birth from profile;
+----+---------+------------+
| id | name    | birth      |
+----+---------+------------+
|  1 | Fred    | 1970-04-13 |
|  2 | Mort    | 1969-09-30 |
|  3 | Brit    | 1957-12-01 |
|  4 | Carl    | 1973-11-02 |
|  5 | Sean    | 1963-07-04 |
|  6 | Alan    | 1965-02-14 |
|  7 | Mara    | 1968-09-17 |
|  8 | Shepard | 1975-09-02 |
|  9 | Dick    | 1952-08-20 |
| 10 | Tony    | 1960-05-01 |
| 11 | Alison  | 1973-01-12 |
| 12 | De'Mont | 1973-01-12 |
| 13 | De'Mont | 1973-01-12 |
| 14 | De'Mont | 1973-01-12 |
| 15 | De'Mont | 1973-01-12 |
| 16 | De'Mont | 1973-01-12 |
| 17 | Amabel  | NULL       |
| 18 | De'Mont | 1980-12-12 |
| 19 | Juan    | NULL       |
| 20 | De'Mont | 1980-12-12 |
+----+---------+------------+
20 rows in set (0.00 sec)

mysql> select schema_name from information_schema.schemata;
+--------------------+
| SCHEMA_NAME        |
+--------------------+
| mysql              |
| information_schema |
| performance_schema |
| sys                |
| cookbook           |
| employees          |
| test_db            |
+--------------------+
7 rows in set (0.02 sec)

mysql> select table_name from information_schema.tables
    -> where table_schema = 'cookbook';
+-----------------------+
| TABLE_NAME            |
+-----------------------+
| actors                |
| adcount               |
。。。。
| weatherdata           |
| weekday               |
+-----------------------+
184 rows in set (0.03 sec)

mysql> select table_name from information_schema.tables
    -> where table_schema = database();
+-----------------------+
| TABLE_NAME            |
+-----------------------+
| actors                |
| adcount               |
。。。。
+-----------------------+
184 rows in set (0.03 sec)

10.6 访问列的定义 375

sql 复制代码
mysql> describe item;
+--------+----------------------------------------------------------------------+------+-----+---------+----------------+
| Field  | Type                                                                 | Null | Key | Default | Extra          |
+--------+----------------------------------------------------------------------+------+-----+---------+----------------+
| id     | int unsigned                                                         | NO   | PRI | NULL    | auto_increment |
| name   | char(20)                                                             | YES  |     | NULL    |                |
| colors | set('chartreuse','mauve','lime green','puce','hot pink','new_color') | YES  |     | NULL    |                |
+--------+----------------------------------------------------------------------+------+-----+---------+----------------+
3 rows in set (0.01 sec)

mysql> select * from information_schema.columns
    -> where table_schema = 'cookbook' and table_name = 'item'
    -> and column_name = 'colors'\G
*************************** 1. row ***************************
           TABLE_CATALOG: def
            TABLE_SCHEMA: cookbook
              TABLE_NAME: item
             COLUMN_NAME: colors
        ORDINAL_POSITION: 3
          COLUMN_DEFAULT: NULL
             IS_NULLABLE: YES
               DATA_TYPE: set
CHARACTER_MAXIMUM_LENGTH: 51
  CHARACTER_OCTET_LENGTH: 204
       NUMERIC_PRECISION: NULL
           NUMERIC_SCALE: NULL
      DATETIME_PRECISION: NULL
      CHARACTER_SET_NAME: utf8mb4
          COLLATION_NAME: utf8mb4_0900_ai_ci
             COLUMN_TYPE: set('chartreuse','mauve','lime green','puce','hot pink','new_color')
              COLUMN_KEY:
                   EXTRA:
              PRIVILEGES: select,insert,update,references
          COLUMN_COMMENT:
   GENERATION_EXPRESSION:
                  SRS_ID: NULL
1 row in set (0.00 sec)

mysql> select column_name, data_type, is_nullable
    -> from information_schema.columns
    -> where table_schema = 'cookbook' and table_name = 'item';
+-------------+-----------+-------------+
| COLUMN_NAME | DATA_TYPE | IS_NULLABLE |
+-------------+-----------+-------------+
| id          | int       | NO          |
| name        | char      | YES         |
| colors      | set       | YES         |
+-------------+-----------+-------------+
3 rows in set (0.00 sec)

mysql> show columns from item like 'colors'\G
*************************** 1. row ***************************
  Field: colors
   Type: set('chartreuse','mauve','lime green','puce','hot pink','new_color')
   Null: YES
    Key:
Default: NULL
  Extra:
1 row in set (0.00 sec)

mysql> show create table item \G
*************************** 1. row ***************************
       Table: item
Create Table: CREATE TABLE `item` (
  `id` int unsigned NOT NULL AUTO_INCREMENT,
  `name` char(20) DEFAULT NULL,
  `colors` set('chartreuse','mauve','lime green','puce','hot pink','new_color') DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.00 sec)

10.7 获取ENUM和SET列的信息 380

sql 复制代码
```python
import pymysql
from pymysql.cursors import DictCursor

def get_enumorset_info(connection, db_name, table_name, column_name):
    """
    获取MySQL表中ENUM或SET类型列的详细信息
    
    参数:
        connection: pymysql连接对象
        db_name: 数据库名
        table_name: 表名
        column_name: 列名
    
    返回:
        包含列信息的字典
    """
    try:
        with connection.cursor(DictCursor) as cursor:
            # 查询列信息
            sql = """
            SELECT COLUMN_TYPE, IS_NULLABLE, COLUMN_DEFAULT, CHARACTER_SET_NAME, COLLATION_NAME
            FROM INFORMATION_SCHEMA.COLUMNS
            WHERE TABLE_SCHEMA = %s
              AND TABLE_NAME = %s
              AND COLUMN_NAME = %s
            """
            cursor.execute(sql, (db_name, table_name, column_name))
            result = cursor.fetchone()
            
            if not result:
                raise ValueError(f"未找到列 '{column_name}' 在表 '{table_name}' 中")
            
            # 解析列类型
            column_type = result['COLUMN_TYPE'].lower()
            col_type = None
            values = []
            
            if column_type.startswith('enum'):
                col_type = 'ENUM'
                # 提取ENUM值
                values_str = column_type[5:-1]  # 移除'enum('和')'
                values = [v.strip("'") for v in values_str.split("','")]
            elif column_type.startswith('set'):
                col_type = 'SET'
                # 提取SET值
                values_str = column_type[4:-1]  # 移除'set('和')'
                values = [v.strip("'") for v in values_str.split("','")]
            else:
                col_type = column_type.upper()
            
            # 处理可为空性
            nullable = result['IS_NULLABLE'] == 'YES'
            
            # 返回结果字典
            return {
                'type': col_type,
                'values': values if col_type in ['ENUM', 'SET'] else [],
                'nullable': nullable,
                'default': result['COLUMN_DEFAULT'],
                'character_set': result['CHARACTER_SET_NAME'],
                'collation': result['COLLATION_NAME']
            }
    except Exception as e:
        print(f"获取列信息时出错: {e}")
        raise

# 连接数据库
conn = pymysql.connect(
    host='localhost',
    user='cbuser',
    password='cbpass',
    database='cookbook'
)

# 获取colors列信息(根据实际表结构修改列名)
info = get_enumorset_info(conn, 'cookbook', 'item', 'colors')  # 修改为存在的列名
print(info)

conn.close()

结果:
{
    'type': 'SET',
    'values': ['chartreuse', 'mauve', 'lime green', 'puce', 'hot pink', 'new_color'],
    'nullable': True,
    'default': None,
    'character_set': 'utf8mb4',
    'collation': 'utf8mb4_general_ci'
}Thursday, July 17, 2025
设计一个汽车零件采购系统的数据库需要考虑多个方面,包括供应商信息、零件信息、采购订单、库存管理
https://programb.blog.csdn.net/article/details/147889220

mysql> -- 创建临时表A
mysql> WITH A AS (
    ->     SELECT 1 AS value UNION ALL
    ->     SELECT 2 UNION ALL
    ->     SELECT 3 UNION ALL
    ->     SELECT 4
    -> ),
    ->
    -> -- 创建临时表B
    -> B AS (
    ->     SELECT 'a' AS letter UNION ALL
    ->     SELECT 'b'
    -> )
    ->
    -> -- 执行CROSS JOIN
    -> SELECT A.value, B.letter
    -> FROM A
    -> CROSS JOIN B
    -> ORDER BY A.value, B.letter;
+-------+--------+
| value | letter |
+-------+--------+
|     1 | a      |
|     1 | b      |
|     2 | a      |
|     2 | b      |
|     3 | a      |
|     3 | b      |
|     4 | a      |
|     4 | b      |
+-------+--------+
8 rows in set (0.00 sec)

itertools --- 为高效循环创建迭代器的函数 --- Python 3.12.10 文档
import itertools
import operator

# 示例1:itertools.product
print(list(itertools.product([1, 2], ['a', 'b'])))

# 示例2:accumulate函数
def accumulate(iterable, function=operator.add, *, initial=None):
    'Return running totals'
    iterator = iter(iterable)
    total = initial
    if initial is None:
        try:
            total = next(iterator)
        except StopIteration:
            return

    yield total
    for element in iterator:
        total = function(total, element)
        yield total

# 测试accumulate函数
print(list(accumulate([1,2,3,4,5])))  # 输出: [1, 3, 6, 10, 15]
print(list(accumulate([1,2,3,4,5], initial=100)))  # 输出: [100, 101, 103, 106, 110, 115]
print(list(accumulate([1,2,3,4,5], operator.mul)))  # 输出: [1, 2, 6, 24, 120]

[(1, 'a'), (1, 'b'), (2, 'a'), (2, 'b')]
[1, 3, 6, 10, 15]
[100, 101, 103, 106, 110, 115]
[1, 2, 6, 24, 120]
复制代码
10.8 获取服务器的元数据 382

```sql
mysql> select version() ;
+-----------+
| version() |
+-----------+
| 8.0.40    |
+-----------+
1 row in set (0.00 sec)

mysql> select database();
+------------+
| database() |
+------------+
| cookbook   |
+------------+
1 row in set (0.00 sec)

mysql> select user();
+----------------+
| user()         |
+----------------+
| root@localhost |
+----------------+
1 row in set (0.00 sec)

mysql> select current_user();
+----------------+
| current_user() |
+----------------+
| root@localhost |
+----------------+
1 row in set (0.00 sec)

在 MySQL 中,SHOW STATUS 命令可以带 GLOBAL 或 SESSION 修饰符,但不能用 [ ] 或 | 表示可选参数。正确的语法是:

sql
SHOW GLOBAL STATUS;    -- 查看全局状态变量
SHOW SESSION STATUS;   -- 查看当前会话状态变量(SESSION 可以省略)
SHOW STATUS;          -- 默认是 SESSION 状态

10.9 编写适合MySQL服务器版本的应用程序 383

sql 复制代码
mysql>
mysql> DROP PROCEDURE IF EXISTS expire_password$$
Query OK, 0 rows affected (0.02 sec)

mysql>
mysql> CREATE PROCEDURE expire_password(IN p_user TEXT, IN p_host TEXT)
    -> BEGIN
    ->     DECLARE v_account TEXT;
    ->
    ->     -- 安全拼接用户名和主机名(处理特殊字符)
    ->     SET v_account = CONCAT('`', REPLACE(p_user, '`', '``'), '`@`', REPLACE(p_host, '`', '``'), '`');
    ->
    ->     -- 调试信息(可选)
    ->     SELECT CONCAT('Executing: ALTER USER ', v_account, ' PASSWORD EXPIRE') AS debug;
    ->
    ->     -- 直接执行(不再检查存在性,因为手动执行已确认可以工作)
    ->     SET @sql = CONCAT('ALTER USER ', v_account, ' PASSWORD EXPIRE');
    ->     PREPARE stmt FROM @sql;
    ->     EXECUTE stmt;
    ->     DEALLOCATE PREPARE stmt;
    ->
    ->     SELECT CONCAT('Success: Password expired for ', v_account) AS result;
    -> END$$
Query OK, 0 rows affected (0.01 sec)

mysql>
mysql> DELIMITER ;
mysql> -- 标准调用(注意host值必须精确匹配)
mysql> CALL expire_password('cbuser', 'localhost');
+------------------------------------------------------------+
| debug                                                      |
+------------------------------------------------------------+
| Executing: ALTER USER `cbuser`@`localhost` PASSWORD EXPIRE |
+------------------------------------------------------------+
1 row in set (0.00 sec)

+----------------------------------------------------+
| result                                             |
+----------------------------------------------------+
| Success: Password expired for `cbuser`@`localhost` |
+----------------------------------------------------+
1 row in set (0.03 sec)

Query OK, 0 rows affected (0.05 sec)

mysql> CALL expire_password('cbuser', 'root');
+-------------------------------------------------------+
| debug                                                 |
+-------------------------------------------------------+
| Executing: ALTER USER `cbuser`@`root` PASSWORD EXPIRE |
+-------------------------------------------------------+
1 row in set (0.00 sec)

+-----------------------------------------------+
| result                                        |
+-----------------------------------------------+
| Success: Password expired for `cbuser`@`root` |
+-----------------------------------------------+
1 row in set (0.03 sec)

Query OK, 0 rows affected (0.04 sec)

mysql>
mysql> -- 如果用户名包含特殊字符(如@)
mysql> CALL expire_password('special@user', 'localhost');
+------------------------------------------------------------------+
| debug                                                            |
+------------------------------------------------------------------+
| Executing: ALTER USER `special@user`@`localhost` PASSWORD EXPIRE |
+------------------------------------------------------------------+
1 row in set (0.00 sec)

ERROR 1396 (HY000): Operation ALTER USER failed for 'special@user'@'localhost'
相关推荐
慕y2742 小时前
Java学习第五十八部分——设计模式
java·学习·设计模式
别致的影分身2 小时前
MySQL InnoDB 存储引擎
数据库·mysql
菜还不练就废了2 小时前
7.19-7.20 Java基础 | File类 I/O流学习笔记
java·笔记·学习
阿諪諪3 小时前
小皮的使用配置
adb
心平愈三千疾3 小时前
学习秒杀系统-页面优化技术
java·学习·面试
为什么名字不能重复呢?3 小时前
Day1||Vue指令学习
前端·vue.js·学习
明早你自己说3 小时前
学习寄存器——GPIO(二)学习BSRR BRR ODR寄存器的原子性和在HAL库的应用
单片机·嵌入式硬件·学习
xinzheng新政3 小时前
纸板制造学习2
学习·制造
试着4 小时前
零基础学习性能测试第一章-性能测试和功能测试的区别
功能测试·学习·零基础·性能测试
试着4 小时前
零基础学习性能测试第一章:核心性能指标-并发量
学习·零基础·性能测试·性能指标·并发量