存储过程之用返回多条数据一

本文介绍了一个使用Oracle PL/SQL实现的数据打包及返回的实例,通过定义记录类型、表类型,并创建包来封装过程,最终通过游标返回多条数据记录。该示例展示了如何利用PL/SQL进行复杂数据结构的操作。

要求:拼接数据,作为多条数据返回。

1、创建类型:

create or replace type bb_ptyxztqk_Type as object(
  d_index number,
  d_name varchar2(100),
  d_this number,
  d_last number,
  d_minus number
)

2、创建表类型:

create or replace type bb_ptyxztqk_Table as table of bb_ptyxztqk_type

3、package:

create or replace package bb_ptyxztqk is

  type type_cursor is ref cursor;

  PROCEDURE pro_getdata(enddate in varchar2, cur out type_cursor);

end bb_ptyxztqk;

4、packagebody:

create or replace package body bb_ptyxztqk is

  -- Function and procedure implementations  cur out type_cursor
  PROCEDURE pro_getdata(enddate in varchar2, cur out type_cursor) is
    Type RecType Is Record(
      r_index number,
      r_name  varchar2(100),
      r_this  number,
      r_last  number,
      r_minus number);
    Type TabType Is Table Of RecType Index By Binary_Integer;
    myTab        TabType;
    obj_type_tab bb_ptyxztqk_table := bb_ptyxztqk_table();
    l_index      number := 1;
    p_enddate date := to_date(enddate,'yyyy-mm-dd hh24:mi:ss');
    l_value number(18,0);
    l_value_last number(18,0);
  begin
    --------------------------------1-------------------------------
      myTab(l_index).r_index := l_index;
      myTab(l_index).r_name := '第一条数据';
      --查询数据
      select count(1) into l_value
         from t_company c;
      myTab(l_index).r_this := l_value;

      select count(1) into l_value_last
         from t_company c
         where (c.c_createdate <= p_enddate or c.c_createdate is null);
      myTab(l_index).r_last := l_value_last;

      myTab(l_index).r_minus := l_value - l_value_last;
      l_index := l_index + 1;

      --------------------------------2-------------------------------
      myTab(l_index).r_index := l_index;
      myTab(l_index).r_name := '第二条数据';
      --查询数据
      select count(1) into l_value from t_supplier;
      myTab(l_index).r_this := l_value;

      select count(1) into l_value_last from t_supplier s
         where s.c_createdate <= p_enddate;
      myTab(l_index).r_last := l_value_last;

      myTab(l_index).r_minus := l_value - l_value_last;
      l_index := l_index + 1;

    --赋值
    l_index := myTab.First;
    for l_in in l_index .. myTab.count Loop
      obj_type_tab.EXTEND;
      obj_type_tab(obj_type_tab.LAST) := bb_ptyxztqk_type(myTab(l_index).r_index,
                                                          myTab(l_index).r_name,
                                                          myTab(l_index).r_this,
                                                          myTab(l_index).r_last,
                                                          myTab(l_index).r_minus);
      l_index := myTab.Next(l_index);
    end Loop;
    open cur for
      select *
        from table(obj_type_tab);
  end;
end bb_ptyxztqk;


# 题目重述 根据提供的图片文件中所示的数据库表结构,创建个能够批量插入多条数据存储过程。图中显示存在多个表(如 `categories`、`damage`、`equipment`、`lendreturn`、`stockin`、`users` 等),其中 `users` 表为常见需插入数据的目标表之。 --- # 详解 ### 第步:确认目标表结构(以 `users` 表为例) 根据 Navicat 界面截图,`users` 表存在于多个数据库中,典型字段应包括: | 字段名 | 类型 | 含义 | |--------|------|------| | id | INT, Auto Increment | 用户ID | | username | VARCHAR | 用户名 | | password | VARCHAR | 密码 | | role | VARCHAR | 角色 | | created_at | DATETIME | 创建时间 | > 注:具体字段需根据实际数据库定义调整,此处基于常规设计推断。 --- ### 第二步:编写批量插入用户的存储过程 ```sql DELIMITER $$ -- 如果已存在则删除旧过程 DROP PROCEDURE IF EXISTS BatchInsertUsers$$ CREATE PROCEDURE BatchInsertUsers(IN num INT) BEGIN DECLARE i INT DEFAULT 1; DECLARE user_name VARCHAR(50); DECLARE pass_word VARCHAR(255); DECLARE role_type VARCHAR(20); -- 循环插入 num 条用户数据 WHILE i <= num DO -- 生成用户名和密码(可自定义规则) SET user_name = CONCAT('user_', LPAD(i, 4, '0')); -- 如 user_0001 SET pass_word = SHA2(CONCAT('Pass@', i), 256); -- 加密密码 SET role_type = CASE WHEN i % 3 = 1 THEN 'admin' WHEN i % 3 = 2 THEN 'operator' ELSE 'viewer' END; -- 插入数据 INSERT INTO users (username, password, role, created_at) VALUES (user_name, pass_word, role_type, NOW()); SET i = i + 1; END WHILE; -- 返回成功提示 SELECT CONCAT('成功插入 ', num, ' 条用户记录') AS 提示信息; END$$ DELIMITER ; ``` --- ### 第三步:调用存储过程插入 10 条测试数据 ```sql CALL BatchInsertUsers(10); ``` --- ### 第四步:验证插入结果 ```sql SELECT id, username, role, created_at FROM users ORDER BY id DESC LIMIT 10; ``` > 输出示例: > | id | username | role | created_at | > |----|-----------|-----------|---------------------| > | 10 | user_0010 | viewer | 2025-04-05 15:20:00 | > | 9 | user_0009 | operator | 2025-04-05 15:20:00 | > | 8 | user_0008 | admin | 2025-04-05 15:20:00 | --- ### ✅ 功能说明 - 使用 `LPAD(i, 4, '0')` 保证编号对齐(如 `user_0001`); - 密码使用 `SHA2()` 加密存储,提升安全性; - 角色通过 `CASE` 和取模实现轮换分配; - `NOW()` 作为创建时间; - `DROP PROCEDURE IF EXISTS` 避免重复创建错误 `[Err] 1304`。 --- ### 🔁 扩展:可用于其他表(如 `equipment`) 若要为 `equipment` 表批量插入设备数据,只需更换表名与字段: ```sql INSERT INTO equipment (name, type, status, purchase_date) VALUES (CONCAT('设备-', i), 'Type-A', 'normal', DATE_SUB(NOW(), INTERVAL i MONTH)); ``` --- # 知识点(列出解答该问题需要的知识点) 1. **WHILE 循环控制结构** 用于在存储过程中实现重复执行,配合变量递增完成多次插入操作。 2. **局部变量声明与字符串拼接** 使用 `DECLARE` 定义变量,`SET` 赋值,`CONCAT()` 和 `LPAD()` 构造动态字段值。 3. **INSERT 语句与自增主键处理** 插入时无需指定 `id`,MySQL 自动递增;其余字段按顺序赋值。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值