达梦数据库dmPython操作数据库手册:Cursor实现增删改查详解

1. Cursor对象概述

Cursor对象是DM数据库Python驱动程序中最重要的组件之一,它提供了执行SQL语句、获取查询结果等核心功能。通过Cursor对象,可以:

  • 执行SQL语句和存储过程
  • 获取查询结果
  • 进行参数绑定
  • 管理事务
  • 处理大字段数据
  • 使用上下文管理器(with语句)
  • 2. Cursor接口方法

    2.1 SQL执行相关

    execute
    Cursor.execute(sql[,parameters]|[,**kwargsParams])
    

    执行给定的SQL语句。支持参数绑定,参数值和SQL语句中的绑定参数从左到右一一对应。如果参数个数不足,剩余参数按None值自动补齐;如果参数过多,则自动忽略。

    示例:

    # 创建表
    cursor.execute("create table test(c1 int, c2 varchar)")
    
    # 按位置动态绑定
    cursor.execute("insert into test values(?, ?)", 1, 'abcdefg')
    
    # 按位置绑定数组
    values = (99, 'today')
    cursor.execute("insert into test values(?, ?)", values)
    
    # 按名称动态绑定
    cursor.execute("insert into test values(:cp1, :cp2)", cp1=1, cp2='abcdefg')
    
    # 按名称绑定字典
    params_map = {'cp1':'99','cp2':'today'}
    cursor.execute("insert into test values(:cp1, :cp2)", params_map)
    
    executedirect
    Cursor.executedirect(sql)
    

    执行给定的SQL语句,不支持参数绑定。

    示例:

    cursor.executedirect("create table test(c1 int, c2 varchar)")
    cursor.executedirect("insert into test values(1, 'abcdefg')")
    
    executemany
    Cursor.executemany(sql, sequence_of_params)
    

    批量执行SQL语句,支持参数绑定。在内存允许范围内,对批量绑定的参数无数量限制。

    示例:

    Seq_params = [(1, 'abcdefg'), (2, 'uvwxyz')]
    cursor.executemany("insert into test values(?, ?)", Seq_params)
    
    prepare
    Cursor.prepare(sql)
    

    预编译SQL语句,提高执行效率。后续可以不指定SQL,直接调用execute。

    注意:以下操作不允许prepare执行:修改数据库状态、修改数据库模式、修改数据库归档模式、修改数据库归档配置、数据库归档文件切换。

    示例:

    cursor.prepare('insert into t_fetch values(?)')
    cursor.execute(None, 1)
    cursor.execute(None, 2)
    cursor.executemany(None, [[3,],[4,]])
    
    close
    Cursor.close()
    

    关闭Cursor对象,释放相关资源。

    2.2 存储过程和函数调用

    callproc
    Cursor.callproc(procname, *args)
    

    调用存储过程,返回执行后的所有输入输出参数序列。

    示例:

    # 无参数存储过程
    cursor.execute('create or replace procedure test_proc_1() as begin print true;end;')
    print(cursor.callproc('test_proc_1'))
    # 输出: []
    
    # 带参数存储过程
    cursor.execute('create or replace procedure test_proc_2(p1 int, p2 out int) as begin p2 = p1 + 1;end;')
    print(cursor.callproc('test_proc_2', 10000, 0))
    # 输出: [10000, 10001]
    
    callfunc
    Cursor.callfunc(funcname, *args)
    

    调用存储函数,返回函数返回值和所有参数值。

    示例:

    # 无参数存储函数
    cursor.execute('create or replace function test_func_1() return int as begin return 123;end;')
    print(cursor.callfunc('test_func_1'))
    # 输出: [123]
    
    # 带参数存储函数
    cursor.execute('create or replace function test_func_2(p1 int, p2 out int) return int as begin p2 = p1 + 1;return 456;end;')
    print(cursor.callfunc('test_func_2', 10000, 0))
    # 输出: [456, 10000, 10001]
    

    2.3 结果集处理

    fetchone/next
    Cursor.fetchone()
    Cursor.next()
    

    获取结果集的下一行,返回tuple或dict类型。

    fetchmany
    Cursor.fetchmany([rows=Cursor.arraysize])
    

    获取多行数据,默认获取行数为Cursor.arraysize值。

    示例:

    cursor.arraysize = 10
    result = cursor.fetchmany(rows=3)
    
    fetchall
    Cursor.fetchall()
    

    获取结果集的所有行。

    nextset
    Cursor.nextset()
    

    获取下一个结果集。

    示例:

    cursor.execute("begin select 1; select 2;end")
    print(cursor.fetchall())  # [(1,)]
    print(cursor.nextset())   # True
    print(cursor.fetchall())  # [(2,)]
    

    3. Cursor属性

    3.1 结果集相关属性

  • arraysize: fetchmany()默认获取的行数,默认值为50
  • 示例:

    # 设置每次获取的行数
    cursor.arraysize = 100
    result = cursor.fetchmany()  # 将获取100行数据
    
  • description: 结果集列描述信息,格式为tuple(name, type_code, display_size, internal_size, precision, scale, null_ok)
  • 示例:

    cursor.execute("select id, name from employees")
    # 获取列描述信息
    for col in cursor.description:
        print(f"列名: {col[0]}, 类型: {col[1]}")
    # 输出示例:
    # 列名: ID, 类型: 2
    # 列名: NAME, 类型: 1
    
  • column_names: 结果集的列名序列
  • 示例:

    cursor.execute("select id, name, salary from employees")
    print(cursor.column_names)  # 输出: ['ID', 'NAME', 'SALARY']
    
  • rowcount: 结果集总数或影响的行数
  • 示例:

    # 查询操作
    cursor.execute("select * from employees where department_id = 10")
    print(f"查询结果行数: {cursor.rowcount}")  # 输出查询结果的行数
    
    # 更新操作
    cursor.execute("update employees set salary = salary * 1.1 where department_id = 20")
    print(f"更新影响行数: {cursor.rowcount}")  # 输出更新影响的行数
    
  • rownumber: 当前行号,从0开始
  • 示例:

    cursor.execute("select * from employees")
    cursor.fetchone()  # 获取第一行
    print(cursor.rownumber)  # 输出: 0
    cursor.fetchone()  # 获取第二行
    print(cursor.rownumber)  # 输出: 1
    
  • with_rows: 是否存在非空结果集
  • 示例:

    # 查询操作
    cursor.execute("select * from employees")
    print(cursor.with_rows)  # 如果有结果,输出: True
    
    # 更新操作
    cursor.execute("update employees set salary = 1000 where 1=0")
    print(cursor.with_rows)  # 无结果集,输出: False
    

    3.2 执行相关属性

  • statement: 最近执行的SQL语句
  • 示例:

    cursor.execute("select * from employees where id = 100")
    print(cursor.statement)  # 输出: select * from employees where id = 100
    
  • lastrowid: 最近一次INSERT/UPDATE操作影响的行的rowid
  • 示例:

    cursor.execute("create table test_rowid(id int identity, name varchar(20))")
    cursor.execute("insert into test_rowid(name) values('张三')")
    print(f"插入行的rowid: {cursor.lastrowid}")  # 输出插入行的rowid值
    
  • execid: SQL语句执行号
  • 示例:

    cursor.execute("select * from employees")
    print(f"SQL执行号: {cursor.execid}")  # 输出当前SQL的执行号
    
  • connection: 当前Cursor对象所在的数据库连接
  • 示例:

    # 获取当前cursor所在的连接对象
    conn = cursor.connection
    # 使用该连接创建新的cursor
    new_cursor = conn.cursor()
    

    4. 大字段操作

    大字段(BLOB/CLOB)的操作与普通字符串类似,使用cursor.execute接口。最大支持长度为2G。

  • Python 3.x: BLOB -> bytes类型,CLOB -> str类型
  • Python 2.x: BLOB -> str类型,CLOB -> unicode类型
  • 示例:

    import sys
    
    # 创建测试数据
    longstring = "ABCDEF0123456789" * 500
    cvalue = longstring
    
    if sys.version_info[0] >= 3:
        bvalue = longstring.encode("ascii")
    else:
        bvalue = longstring
    
    # 创建表并插入数据
    cursor.execute('create table t_lob(c1 blob, c2 clob)')
    cursor.execute('insert into t_lob values(?, ?)', bvalue, cvalue)
    
    # 查询数据
    cursor.execute('select * from t_lob')
    row = cursor.fetchone()
    (blob, clob) = row
    

    作者:杜甫不忙

    物联沃分享整理
    物联沃-IOTWORD物联网 » 达梦数据库dmPython操作数据库手册:Cursor实现增删改查详解

    发表回复