Rust & MySQL: executing MySQL stored procedures which return multiple result sets using crate sqlx.

behainguyen

Be Hai Nguyen

Posted on September 17, 2023

Rust & MySQL: executing MySQL stored procedures which return multiple result sets using crate sqlx.

MySQL stored procedures can return multiple result sets. In this post, we’re looking at calling such stored procedure. For each returned record set, we extract column values into a corresponding struct instance; and store this instance in a vector.

This post is a continuation of:

  1. Rust & MySQL: connect, execute SQL statements and stored procs using crate sqlx.
  2. Rust & MySQL: delete, insert data using crate sqlx.

We'll use the same Oracle Corporation MySQL test data database. This time, we'll use the departments and the dept_manager tables.

The departments table:

CREATE TABLE `departments` (
  `dept_no` char(4) NOT NULL,
  `dept_name` varchar(40) NOT NULL,
  PRIMARY KEY (`dept_no`),
  UNIQUE KEY `dept_name` (`dept_name`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Enter fullscreen mode Exit fullscreen mode

The dept_manager table:

CREATE TABLE `dept_manager` (
  `emp_no` int NOT NULL,
  `dept_no` char(4) NOT NULL,
  `from_date` date NOT NULL,
  `to_date` date NOT NULL,
  PRIMARY KEY (`emp_no`,`dept_no`),
  KEY `dept_no` (`dept_no`),
  CONSTRAINT `dept_manager_ibfk_1` FOREIGN KEY (`emp_no`) REFERENCES `employees` (`emp_no`) ON DELETE CASCADE,
  CONSTRAINT `dept_manager_ibfk_2` FOREIGN KEY (`dept_no`) REFERENCES `departments` (`dept_no`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Enter fullscreen mode Exit fullscreen mode

The DemoStoredProc1 stored procedure:

DELIMITER $$
CREATE DEFINER=`root`@`%` PROCEDURE `DemoStoredProc1`( pm_dept_no varchar(4) )
    READS SQL DATA
begin
  select * from departments where dept_no = pm_dept_no;
  select * from dept_manager where dept_no = pm_dept_no;
end$$
DELIMITER ;
Enter fullscreen mode Exit fullscreen mode

Stored procedure DemoStoredProc1(pm_dept_no varchar(4)) returns two result sets whose data come from tables departments and dept_manager respectively.

Please note: the example code has been tested on both Windows 10 and Ubuntu 22.10.

❀❀❀

I could not find any example or documentation on this multiple result sets issue. The final example code is the result of experimentation with crate sqlx.

The final dependencies section of the Cargo.toml file used in this post:

...
[dependencies]
async-std = "1.12.0"
sqlx = {version = "0.7", default-features = false, features = ["runtime-async-std", "macros", "mysql", "time"]}
Enter fullscreen mode Exit fullscreen mode

To keep the example simple, we won't do time formatting, hence we don't need crate time.

As you can guess, for the example, we'll call the stored procedure DemoStoredProc1 with a 4-character dept_no. The first resultant record set, from the departments table, will have at most one (1) record. The second resultant record set, from the dept_manager table, will have at least one (1) record.

The complete working example is presented below.

Content of src/main.rs:
Enter fullscreen mode Exit fullscreen mode
use sqlx::{FromRow, Pool, MySql, Error, MySqlPool, Row};
use sqlx::types::time::Date;

use async_std::task;

#[derive(FromRow, Debug)]
pub struct Department {
    pub dept_no: String,
    pub dept_name: String,
}

#[derive(FromRow, Debug)]
pub struct DepartmentManager {
    pub emp_no: i32,
    pub dept_no: String,
    pub from_date: Date,
    pub to_date: Date,
}

async fn connect() -> Result<Pool<MySql>, Error> {
    return MySqlPool::connect("mysql://root:pcb.2176310315865259@localhost:3306/employees").await;
}

async fn do_run_stored_proc(pool: &sqlx::Pool<MySql>, dept_no: &str) {
    let result = sqlx::query("call DemoStoredProc1(?)")
    .bind(dept_no)
    .fetch_all(pool).await;

    match result {
        Err(e) => {
            println!("Error select data for department number: {}", dept_no);
            println!("Error message: [{}].\n", e.to_string());
        }

        Ok(query_result) => {
            let mut dept_vec = Vec::<Department>::new(); 
            let mut dept_mgr_vec = Vec::<DepartmentManager>::new();

            println!("dept_vec.len() = {}", dept_vec.len());
            println!("dept_mgr_vec.len() = {}", dept_mgr_vec.len());

            for row in query_result {
                if row.columns().len() == 2 {
                    dept_vec.push(Department{dept_no: row.get(0), dept_name: row.get(1)});
                }
                else {
                    dept_mgr_vec.push(DepartmentManager{
                        emp_no: row.get(0),
                        dept_no: row.get(1),
                        from_date: row.get(2),
                        to_date: row.get(3),
                    });
                }
            }

            println!("{:#?}", dept_vec);
            println!("{:#?}", dept_mgr_vec);
        }
    }
}

fn main() {
    let result: Result<sqlx::Pool<sqlx::MySql>, sqlx::Error> = task::block_on(connect());

    match result {
        Err(err) => {
            println!("Cannot connect to database [{}]", err.to_string());
        }        

        Ok(pool) => {
            task::block_on(do_run_stored_proc(&pool, "d009"));
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

The code is pretty much a refactored version of the code in the previous two mentioned posts. We declare two (2) new structs: Department and DepartmentManager to capture the two (2) result sets.

We're interested the for loop in async fn do_run_stored_proc(pool: &sqlx::Pool<MySql>, dept_no: &str):

            ...
            for row in query_result {
                if row.columns().len() == 2 {
                    dept_vec.push(Department{dept_no: row.get(0), dept_name: row.get(1)});
                }
                else {
                    dept_mgr_vec.push(DepartmentManager{
                        emp_no: row.get(0),
                        dept_no: row.get(1),
                        from_date: row.get(2),
                        to_date: row.get(3),
                    });
                }
            }
            ...
Enter fullscreen mode Exit fullscreen mode

Basically, for each row, if there're two (2) columns, we extract the values into an instance of the struct Department, and push this instance onto vector dept_vec. Otherwise, the row values go to an instance of the struct DepartmentManager, and this instance goes to vector dept_mgr_vec. This logic is very weak. What should we do if the stored procedure returns three (3) result sets, and two (2) of them have two (2) columns each? But, for the purpose of this post, we'll ignore this issue.

⓵ As mentioned previously, I've done several iterations before this final version of the code. My first attempt looking at the returned result is:

            ...
            for (rindex, row) in query_result.iter().enumerate() {
                println!("* Row number: {}", rindex+1);
                println!("* Total columns: {}", row.columns().len());
                println!("{:#?}\n", row);
            }
            ...
Enter fullscreen mode Exit fullscreen mode

In total, there are only five (5) rows returned between the two (2) result sets, but the output is pretty long. Please see section First Iteration Output for the full printout.

⓶ Based on the output, we can see that all result sets returned. And there are no separate result sets. There're just rows, with different column meta. My first attempt, then, at extracting values out is to get the column data type, then case out (match) the data type: i.e. for each column data type, declare a variable of corresponding type, and extract the target column value into this variable. My attempt at getting the column data type:

use sqlx::{FromRow, Pool, MySql, Error, MySqlPool, Row, TypeInfo, Column};
...
            ...
            for (rindex, row) in query_result.iter().enumerate() {
                println!("* Row number: {}", rindex+1);
                println!("* Total columns: {}\n", row.columns().len());

                for (cindex, col) in row.columns().iter().enumerate() {
                    println!("{:#?}", col.type_info());
                    // println!("> {}. Name: {}. Value: {}.", cindex+1, col.name(), row.get(cindex));
                    println!("> {}. Name: {}. Type Name: {}.", cindex+1, col.name(), col.type_info().name());
                }
            }
            ...
Enter fullscreen mode Exit fullscreen mode

-- Note, the two (2) additional traits added to the use declarations: Trait sqlx::TypeInfo and trait sqlx::Column.

Please see section Second Iteration Output for the output of the above for loop. Trait sqlx::TypeInfo and struct sqlx_mysql::MySqlTypeInfo do give info on column meta data. But still I could not get to pub enum ColumnType, and the documentation does not seem to have anything about pub enum ColumnType either (?).

In hindsight, checking individual columns' data types, declaring variables, etc. is a bad idea... I can see in my mind, how messy, and error prone the code is going to be. I'm not sure if the above solution is a correct or even an acceptable one, but it seems much cleaner.

Again, this post is just a documentation of my learning progress. I do hope someone would find it useful. Thank you for reading and stay safe as always.

✿✿✿

Feature image source:

✿✿✿

First Iteration Output

* Row number: 1
* Total columns: 2
MySqlRow {
    row: Row {
        storage: b"\0\x04d009\x10Customer Service",
        values: [
            Some(
                2..6,
            ),
            Some(
                7..23,
            ),
        ],
    },
    format: Binary,
    columns: [
        MySqlColumn {
            ordinal: 0,
            name: dept_no,
            type_info: MySqlTypeInfo {
                type: String,
                flags: ColumnFlags(
                    NOT_NULL | PRIMARY_KEY | NO_DEFAULT_VALUE,
                ),
                char_set: 224,
                max_size: Some(
                    16,
                ),
            },
            flags: Some(
                ColumnFlags(
                    NOT_NULL | PRIMARY_KEY | NO_DEFAULT_VALUE,
                ),
            ),
        },
        MySqlColumn {
            ordinal: 1,
            name: dept_name,
            type_info: MySqlTypeInfo {
                type: VarString,
                flags: ColumnFlags(
                    NOT_NULL | UNIQUE_KEY | NO_DEFAULT_VALUE,
                ),
                char_set: 224,
                max_size: Some(
                    160,
                ),
            },
            flags: Some(
                ColumnFlags(
                    NOT_NULL | UNIQUE_KEY | NO_DEFAULT_VALUE,
                ),
            ),
        },
    ],
    column_names: {},
}

* Row number: 2
* Total columns: 4
MySqlRow {
    row: Row {
        storage: b"\0L\xb4\x01\0\x04d009\x04\xc1\x07\x01\x01\x04\xc4\x07\n\x11",
        values: [
            Some(
                1..5,
            ),
            Some(
                6..10,
            ),
            Some(
                10..15,
            ),
            Some(
                15..20,
            ),
        ],
    },
    format: Binary,
    columns: [
        MySqlColumn {
            ordinal: 0,
            name: emp_no,
            type_info: MySqlTypeInfo {
                type: Long,
                flags: ColumnFlags(
                    NOT_NULL | PRIMARY_KEY | NO_DEFAULT_VALUE,
                ),
                char_set: 63,
                max_size: Some(
                    11,
                ),
            },
            flags: Some(
                ColumnFlags(
                    NOT_NULL | PRIMARY_KEY | NO_DEFAULT_VALUE,
                ),
            ),
        },
        MySqlColumn {
            ordinal: 1,
            name: dept_no,
            type_info: MySqlTypeInfo {
                type: String,
                flags: ColumnFlags(
                    NOT_NULL | PRIMARY_KEY | MULTIPLE_KEY | NO_DEFAULT_VALUE,
                ),
                char_set: 224,
                max_size: Some(
                    16,
                ),
            },
            flags: Some(
                ColumnFlags(
                    NOT_NULL | PRIMARY_KEY | MULTIPLE_KEY | NO_DEFAULT_VALUE,
                ),
            ),
        },
        MySqlColumn {
            ordinal: 2,
            name: from_date,
            type_info: MySqlTypeInfo {
                type: Date,
                flags: ColumnFlags(
                    NOT_NULL | BINARY | NO_DEFAULT_VALUE,
                ),
                char_set: 63,
                max_size: Some(
                    10,
                ),
            },
            flags: Some(
                ColumnFlags(
                    NOT_NULL | BINARY | NO_DEFAULT_VALUE,
                ),
            ),
        },
        MySqlColumn {
            ordinal: 3,
            name: to_date,
            type_info: MySqlTypeInfo {
                type: Date,
                flags: ColumnFlags(
                    NOT_NULL | BINARY | NO_DEFAULT_VALUE,
                ),
                char_set: 63,
                max_size: Some(
                    10,
                ),
            },
            flags: Some(
                ColumnFlags(
                    NOT_NULL | BINARY | NO_DEFAULT_VALUE,
                ),
            ),
        },
    ],
    column_names: {
        emp_no: 0,
        dept_no: 1,
        from_date: 2,
        to_date: 3,
    },
}

* Row number: 3
* Total columns: 4
MySqlRow {
    row: Row {
        storage: b"\0\xa8\xb4\x01\0\x04d009\x04\xc4\x07\n\x11\x04\xc8\x07\t\x08",
        values: [
            Some(
                1..5,
            ),
            Some(
                6..10,
            ),
            Some(
                10..15,
            ),
            Some(
                15..20,
            ),
        ],
    },
    format: Binary,
    columns: [
        MySqlColumn {
            ordinal: 0,
            name: emp_no,
            type_info: MySqlTypeInfo {
                type: Long,
                flags: ColumnFlags(
                    NOT_NULL | PRIMARY_KEY | NO_DEFAULT_VALUE,
                ),
                char_set: 63,
                max_size: Some(
                    11,
                ),
            },
            flags: Some(
                ColumnFlags(
                    NOT_NULL | PRIMARY_KEY | NO_DEFAULT_VALUE,
                ),
            ),
        },
        MySqlColumn {
            ordinal: 1,
            name: dept_no,
            type_info: MySqlTypeInfo {
                type: String,
                flags: ColumnFlags(
                    NOT_NULL | PRIMARY_KEY | MULTIPLE_KEY | NO_DEFAULT_VALUE,
                ),
                char_set: 224,
                max_size: Some(
                    16,
                ),
            },
            flags: Some(
                ColumnFlags(
                    NOT_NULL | PRIMARY_KEY | MULTIPLE_KEY | NO_DEFAULT_VALUE,
                ),
            ),
        },
        MySqlColumn {
            ordinal: 2,
            name: from_date,
            type_info: MySqlTypeInfo {
                type: Date,
                flags: ColumnFlags(
                    NOT_NULL | BINARY | NO_DEFAULT_VALUE,
                ),
                char_set: 63,
                max_size: Some(
                    10,
                ),
            },
            flags: Some(
                ColumnFlags(
                    NOT_NULL | BINARY | NO_DEFAULT_VALUE,
                ),
            ),
        },
        MySqlColumn {
            ordinal: 3,
            name: to_date,
            type_info: MySqlTypeInfo {
                type: Date,
                flags: ColumnFlags(
                    NOT_NULL | BINARY | NO_DEFAULT_VALUE,
                ),
                char_set: 63,
                max_size: Some(
                    10,
                ),
            },
            flags: Some(
                ColumnFlags(
                    NOT_NULL | BINARY | NO_DEFAULT_VALUE,
                ),
            ),
        },
    ],
    column_names: {
        emp_no: 0,
        dept_no: 1,
        from_date: 2,
        to_date: 3,
    },
}

* Row number: 4
* Total columns: 4
MySqlRow {
    row: Row {
        storage: b"\0\x05\xb5\x01\0\x04d009\x04\xc8\x07\t\x08\x04\xcc\x07\x01\x03",
        values: [
            Some(
                1..5,
            ),
            Some(
                6..10,
            ),
            Some(
                10..15,
            ),
            Some(
                15..20,
            ),
        ],
    },
    format: Binary,
    columns: [
        MySqlColumn {
            ordinal: 0,
            name: emp_no,
            type_info: MySqlTypeInfo {
                type: Long,
                flags: ColumnFlags(
                    NOT_NULL | PRIMARY_KEY | NO_DEFAULT_VALUE,
                ),
                char_set: 63,
                max_size: Some(
                    11,
                ),
            },
            flags: Some(
                ColumnFlags(
                    NOT_NULL | PRIMARY_KEY | NO_DEFAULT_VALUE,
                ),
            ),
        },
        MySqlColumn {
            ordinal: 1,
            name: dept_no,
            type_info: MySqlTypeInfo {
                type: String,
                flags: ColumnFlags(
                    NOT_NULL | PRIMARY_KEY | MULTIPLE_KEY | NO_DEFAULT_VALUE,
                ),
                char_set: 224,
                max_size: Some(
                    16,
                ),
            },
            flags: Some(
                ColumnFlags(
                    NOT_NULL | PRIMARY_KEY | MULTIPLE_KEY | NO_DEFAULT_VALUE,
                ),
            ),
        },
        MySqlColumn {
            ordinal: 2,
            name: from_date,
            type_info: MySqlTypeInfo {
                type: Date,
                flags: ColumnFlags(
                    NOT_NULL | BINARY | NO_DEFAULT_VALUE,
                ),
                char_set: 63,
                max_size: Some(
                    10,
                ),
            },
            flags: Some(
                ColumnFlags(
                    NOT_NULL | BINARY | NO_DEFAULT_VALUE,
                ),
            ),
        },
        MySqlColumn {
            ordinal: 3,
            name: to_date,
            type_info: MySqlTypeInfo {
                type: Date,
                flags: ColumnFlags(
                    NOT_NULL | BINARY | NO_DEFAULT_VALUE,
                ),
                char_set: 63,
                max_size: Some(
                    10,
                ),
            },
            flags: Some(
                ColumnFlags(
                    NOT_NULL | BINARY | NO_DEFAULT_VALUE,
                ),
            ),
        },
    ],
    column_names: {
        emp_no: 0,
        dept_no: 1,
        from_date: 2,
        to_date: 3,
    },
}

* Row number: 5
* Total columns: 4
MySqlRow {
    row: Row {
        storage: b"\0C\xb5\x01\0\x04d009\x04\xcc\x07\x01\x03\x04\x0f'\x01\x01",
        values: [
            Some(
                1..5,
            ),
            Some(
                6..10,
            ),
            Some(
                10..15,
            ),
            Some(
                15..20,
            ),
        ],
    },
    format: Binary,
    columns: [
        MySqlColumn {
            ordinal: 0,
            name: emp_no,
            type_info: MySqlTypeInfo {
                type: Long,
                flags: ColumnFlags(
                    NOT_NULL | PRIMARY_KEY | NO_DEFAULT_VALUE,
                ),
                char_set: 63,
                max_size: Some(
                    11,
                ),
            },
            flags: Some(
                ColumnFlags(
                    NOT_NULL | PRIMARY_KEY | NO_DEFAULT_VALUE,
                ),
            ),
        },
        MySqlColumn {
            ordinal: 1,
            name: dept_no,
            type_info: MySqlTypeInfo {
                type: String,
                flags: ColumnFlags(
                    NOT_NULL | PRIMARY_KEY | MULTIPLE_KEY | NO_DEFAULT_VALUE,
                ),
                char_set: 224,
                max_size: Some(
                    16,
                ),
            },
            flags: Some(
                ColumnFlags(
                    NOT_NULL | PRIMARY_KEY | MULTIPLE_KEY | NO_DEFAULT_VALUE,
                ),
            ),
        },
        MySqlColumn {
            ordinal: 2,
            name: from_date,
            type_info: MySqlTypeInfo {
                type: Date,
                flags: ColumnFlags(
                    NOT_NULL | BINARY | NO_DEFAULT_VALUE,
                ),
                char_set: 63,
                max_size: Some(
                    10,
                ),
            },
            flags: Some(
                ColumnFlags(
                    NOT_NULL | BINARY | NO_DEFAULT_VALUE,
                ),
            ),
        },
        MySqlColumn {
            ordinal: 3,
            name: to_date,
            type_info: MySqlTypeInfo {
                type: Date,
                flags: ColumnFlags(
                    NOT_NULL | BINARY | NO_DEFAULT_VALUE,
                ),
                char_set: 63,
                max_size: Some(
                    10,
                ),
            },
            flags: Some(
                ColumnFlags(
                    NOT_NULL | BINARY | NO_DEFAULT_VALUE,
                ),
            ),
        },
    ],
    column_names: {
        emp_no: 0,
        dept_no: 1,
        from_date: 2,
        to_date: 3,
    },
}
Enter fullscreen mode Exit fullscreen mode

Second Iteration Output

* Row number: 1
* Total columns: 2

MySqlTypeInfo {
    type: String,
    flags: ColumnFlags(
        NOT_NULL | PRIMARY_KEY | NO_DEFAULT_VALUE,
    ),
    char_set: 224,
    max_size: Some(
        16,
    ),
}
> 1. Name: dept_no. Type Name: CHAR.
MySqlTypeInfo {
    type: VarString,
    flags: ColumnFlags(
        NOT_NULL | UNIQUE_KEY | NO_DEFAULT_VALUE,
    ),
    char_set: 224,
    max_size: Some(
        160,
    ),
}
> 2. Name: dept_name. Type Name: VARCHAR.
* Row number: 2
* Total columns: 4

MySqlTypeInfo {
    type: Long,
    flags: ColumnFlags(
        NOT_NULL | PRIMARY_KEY | NO_DEFAULT_VALUE,
    ),
    char_set: 63,
    max_size: Some(
        11,
    ),
}
> 1. Name: emp_no. Type Name: INT.
MySqlTypeInfo {
    type: String,
    flags: ColumnFlags(
        NOT_NULL | PRIMARY_KEY | MULTIPLE_KEY | NO_DEFAULT_VALUE,
    ),
    char_set: 224,
    max_size: Some(
        16,
    ),
}
> 2. Name: dept_no. Type Name: CHAR.
MySqlTypeInfo {
    type: Date,
    flags: ColumnFlags(
        NOT_NULL | BINARY | NO_DEFAULT_VALUE,
    ),
    char_set: 63,
    max_size: Some(
        10,
    ),
}
> 3. Name: from_date. Type Name: DATE.
MySqlTypeInfo {
    type: Date,
    flags: ColumnFlags(
        NOT_NULL | BINARY | NO_DEFAULT_VALUE,
    ),
    char_set: 63,
    max_size: Some(
        10,
    ),
}
> 4. Name: to_date. Type Name: DATE.
* Row number: 3
* Total columns: 4

MySqlTypeInfo {
    type: Long,
    flags: ColumnFlags(
        NOT_NULL | PRIMARY_KEY | NO_DEFAULT_VALUE,
    ),
    char_set: 63,
    max_size: Some(
        11,
    ),
}
> 1. Name: emp_no. Type Name: INT.
MySqlTypeInfo {
    type: String,
    flags: ColumnFlags(
        NOT_NULL | PRIMARY_KEY | MULTIPLE_KEY | NO_DEFAULT_VALUE,
    ),
    char_set: 224,
    max_size: Some(
        16,
    ),
}
> 2. Name: dept_no. Type Name: CHAR.
MySqlTypeInfo {
    type: Date,
    flags: ColumnFlags(
        NOT_NULL | BINARY | NO_DEFAULT_VALUE,
    ),
    char_set: 63,
    max_size: Some(
        10,
    ),
}
> 3. Name: from_date. Type Name: DATE.
MySqlTypeInfo {
    type: Date,
    flags: ColumnFlags(
        NOT_NULL | BINARY | NO_DEFAULT_VALUE,
    ),
    char_set: 63,
    max_size: Some(
        10,
    ),
}
> 4. Name: to_date. Type Name: DATE.
* Row number: 4
* Total columns: 4

MySqlTypeInfo {
    type: Long,
    flags: ColumnFlags(
        NOT_NULL | PRIMARY_KEY | NO_DEFAULT_VALUE,
    ),
    char_set: 63,
    max_size: Some(
        11,
    ),
}
> 1. Name: emp_no. Type Name: INT.
MySqlTypeInfo {
    type: String,
    flags: ColumnFlags(
        NOT_NULL | PRIMARY_KEY | MULTIPLE_KEY | NO_DEFAULT_VALUE,
    ),
    char_set: 224,
    max_size: Some(
        16,
    ),
}
> 2. Name: dept_no. Type Name: CHAR.
MySqlTypeInfo {
    type: Date,
    flags: ColumnFlags(
        NOT_NULL | BINARY | NO_DEFAULT_VALUE,
    ),
    char_set: 63,
    max_size: Some(
        10,
    ),
}
> 3. Name: from_date. Type Name: DATE.
MySqlTypeInfo {
    type: Date,
    flags: ColumnFlags(
        NOT_NULL | BINARY | NO_DEFAULT_VALUE,
    ),
    char_set: 63,
    max_size: Some(
        10,
    ),
}
> 4. Name: to_date. Type Name: DATE.
* Row number: 5
* Total columns: 4

MySqlTypeInfo {
    type: Long,
    flags: ColumnFlags(
        NOT_NULL | PRIMARY_KEY | NO_DEFAULT_VALUE,
    ),
    char_set: 63,
    max_size: Some(
        11,
    ),
}
> 1. Name: emp_no. Type Name: INT.
MySqlTypeInfo {
    type: String,
    flags: ColumnFlags(
        NOT_NULL | PRIMARY_KEY | MULTIPLE_KEY | NO_DEFAULT_VALUE,
    ),
    char_set: 224,
    max_size: Some(
        16,
    ),
}
> 2. Name: dept_no. Type Name: CHAR.
MySqlTypeInfo {
    type: Date,
    flags: ColumnFlags(
        NOT_NULL | BINARY | NO_DEFAULT_VALUE,
    ),
    char_set: 63,
    max_size: Some(
        10,
    ),
}
> 3. Name: from_date. Type Name: DATE.
MySqlTypeInfo {
    type: Date,
    flags: ColumnFlags(
        NOT_NULL | BINARY | NO_DEFAULT_VALUE,
    ),
    char_set: 63,
    max_size: Some(
        10,
    ),
}
> 4. Name: to_date. Type Name: DATE.
Enter fullscreen mode Exit fullscreen mode
💖 💪 🙅 🚩
behainguyen
Be Hai Nguyen

Posted on September 17, 2023

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related