暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

在 openGauss 中使用游标

openGauss 2024-12-16
276

游标(Cursor)是数据库中的一种数据访问机制,允许用户逐行处理查询结果集。在 OpenGauss 中,游标分为显式游标和隐式游标。本文将详细介绍这两种游标的使用方法,并提供具体的示例。

表结构

    CREATE TABLE employees (
    id INT PRIMARY KEY,
    name VARCHAR(100),
    salary DECIMAL(10, 2),
    department_id INT
    );


    INSERT INTO employees (id, name, salary, department_id) VALUES
    (1, 'Alice', 50000.00, 101),
    (2, 'Bob', 60000.00, 102),
    (3, 'Charlie', 70000.00, 101),
    (4, 'David', 80000.00, 103);

    显式游标示例

    显式游标需要手动定义、打开、读取和关闭。

      DO $$
      DECLARE
      -- 定义游标
      CURSOR emp_cursor FOR SELECT id, name, salary FROM employees;
      -- 定义变量来存储从游标中获取的值
      emp_id INT;
      emp_name VARCHAR(100);
      emp_salary DECIMAL(10, 2);
      BEGIN
      -- 打开游标
      OPEN emp_cursor;


      -- 逐行读取数据
      LOOP
      FETCH NEXT FROM emp_cursor INTO emp_id, emp_name, emp_salary;
      EXIT WHEN NOT FOUND; -- 当没有更多数据时退出循环


      -- 处理数据,这里只是简单地打印出来
      RAISE NOTICE 'Employee ID: %, Name: %, Salary: %', emp_id, emp_name, emp_salary;
      END LOOP;


      -- 关闭游标
      CLOSE emp_cursor;
      END $$;


      /*输出结果:
      NOTICE: Employee ID: 1, Name: Alice, Salary: 50000.00
      NOTICE: Employee ID: 2, Name: Bob, Salary: 60000.00
      NOTICE: Employee ID: 3, Name: Charlie, Salary: 70000.00
      NOTICE: Employee ID: 4, Name: David, Salary: 80000.00
      ANONYMOUS BLOCK EXECUTE
      */

      隐式游标示例

      隐式游标不需要手动管理,通常在执行 DML 语句(如 SELECT INTO
      UPDATE
      DELETE
      )时自动使用。

        DO $$
        DECLARE
        -- 定义变量来存储从查询中获取的值
        emp_id INT;
        emp_name VARCHAR(100);
        emp_salary DECIMAL(10, 2);
        BEGIN
        -- 使用隐式游标从表中读取数据
        FOR emp_record IN (SELECT id, name, salary FROM employees)
        LOOP
        -- 将查询结果赋值给变量
        emp_id := emp_record.id;
        emp_name := emp_record.name;
        emp_salary := emp_record.salary;


        -- 处理数据,这里只是简单地打印出来
        RAISE NOTICE 'Employee ID: %, Name: %, Salary: %', emp_id, emp_name, emp_salary;
        END LOOP;
        END $$;


        /*输出结果:
        NOTICE: Employee ID: 1, Name: Alice, Salary: 50000.00
        NOTICE: Employee ID: 2, Name: Bob, Salary: 60000.00
        NOTICE: Employee ID: 3, Name: Charlie, Salary: 70000.00
        NOTICE: Employee ID: 4, Name: David, Salary: 80000.00
        ANONYMOUS BLOCK EXECUTE
        */

        解释

        显式游标

        1. 定义游标

          CURSOR emp_cursor FOR SELECT id, name, salary FROM employees;

          这里定义了一个游标 emp_cursor
          ,该游标执行的查询是从 employees
           表中选择 id
          name
          salary
           字段。

          2. 定义变量:

            emp_id INT;
            emp_name VARCHAR(100);
            emp_salary DECIMAL(10, 2);

            这些变量用于存储从游标中获取的每行数据。

            3. 打开游标

              OPEN emp_cursor;

              执行查询并准备数据。

              4. 读取数据:

                FETCH NEXT FROM emp_cursor INTO emp_id, emp_name, emp_salary;

                从游标中读取一行数据并将其存储到变量中。

                5. 循环处理:

                  LOOP
                  FETCH NEXT FROM emp_cursor INTO emp_id, emp_name, emp_salary;
                  EXIT WHEN NOT FOUND; -- 当没有更多数据时退出循环


                  -- 处理数据,这里只是简单地打印出来
                  RAISE NOTICE 'Employee ID: %, Name: %, Salary: %', emp_id, emp_name, emp_salary;
                  END LOOP;

                  LOOP
                   结构用于逐行处理数据,EXIT WHEN NOT FOUND;
                   用于在没有更多数据时退出循环。

                  6. 关闭游标:

                    CLOSE emp_cursor;

                    释放游标占用的资源。

                    隐式游标

                    1. 定义变量

                      emp_id INT;
                      emp_name VARCHAR(100);
                      emp_salary DECIMAL(10, 2);

                      这些变量用于存储从查询中获取的每行数据。

                      2. 使用隐式游标从表中读取数据:

                        FOR emp_record IN (SELECT id, name, salary FROM employees)
                        LOOP
                        -- 将查询结果赋值给变量
                        emp_id := emp_record.id;
                        emp_name := emp_record.name;
                        emp_salary := emp_record.salary;


                        -- 处理数据,这里只是简单地打印出来
                        RAISE NOTICE 'Employee ID: %, Name: %, Salary: %', emp_id, emp_name, emp_salary;
                        END LOOP;

                        FOR
                         循环会自动处理查询结果集中的每一行,并将每一行的数据赋值给 emp_record
                         记录,然后你可以从中提取各个字段的值。


                        点击阅读原文跳转作者文章

                        文章转载自openGauss,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

                        评论