批处理语句执行

使用 Cursor.executemany()可以有效地插入或更新多行,从而轻松处理具有STPython的大型数据集。此方法通过降低网络传输成本和数据库开销,可以显著优于对 Cursor.execute()的重复调用。executemany() 方法还可用于一次多次执行 PL/SQL 语句。

如:

data = [
    ('Parent 10',11),
    ('Parent 20',12),
    ('Parent 30',13),
    ('Parent 40',14),
    ('Parent 50',15)
]

cursor.executemany("insert into mytab values (:1, :2)", data)
connection.commit()

此代码只需要从客户端到数据库的一次往返,而不是重复调用execute()所需的五次往返行程。对于非常大的数据集,可能存在外部缓冲区或网络对可以处理的行数的限制,因此可能需要重复调用。这些限制基于正在处理的行数以及正在处理的每一行的“大小”。对 executemany() 的重复调用仍然比对 execute() 的重复调用更好。

插入、更新、删除和合并等 DML 语句可以使用 DML RETURN 语法返回值。可以创建绑定变量来接受此数据。有关详细信息,请参阅使用绑定变量。 想知道有关已删除的每一行的一些信息,则可以使用以下代码:

ids_to_delete = [1, 2, 3]
id_var = cursor.var(int, arraysize=len(ids_to_delete))
cursor.setinputsizes(None, id_var)
cursor.executemany("""
        delete from mytab
        where b = :1
        returning b into :2""",
        [(i,) for i in ids_to_delete])
print(id_var)

然后,输出将为:

<STPython.NUMBER with value [1, 2, 3]>

请注意,为接受返回的数据而创建的绑定变量必须具有足够大的数组大小,以保存所处理的每一行的数据。此外,对 Cursor.setinputsizes() 的调用会立即绑定此变量,这样就不必在每行数据中传递它。

大容量加载

大容量导入的设计采用异步模式,应用程序将数据持续的放到加载缓存中,如果缓存中的数据超过了设定的提交行数或缓存大小,会自动的将缓存中的数据提交到数据库表中。 Bulk.addrow添加单行数据;Bulk.addrows添加多行数据,可以添加单行数据,数据格式可以是[(...), (...), ...], 也可以是[[...], [...], ...]。 初始化Bulk对象时,schema、colsDesc、bufferSize是可选参数

注解

字段类型:python里的字节(bytes)类型对应数据库里VARBINARY类型,python里的其余类型都安装字符串方式插入到数据库,对应数据库里VARCHAR类型。

import STPython

bufferSize = 1024
table_name= "tabBulk"
schema = 'SYSDBA'

csql = """
create table IF NOT EXISTS tabBulk(
    col_str VARCHAR(100),
    col_bytes VARBINARY(5000),
    col_int int,
    col_float float,
    col_list VARCHAR(50),
    col_dict VARCHAR(50),
    col_tuple VARCHAR(50),
    col_none VARCHAR(10),
    col_datetime VARCHAR(50)
    )
"""

dsql = "drop table IF EXISTS tabBulk"

cols_desc = """
    col_str VARCHAR(100),
    col_bytes VARBINARY(5000),
    col_int int,
    col_float float,
    col_list VARCHAR(50),
    col_dict VARCHAR(50),
    col_tuple VARCHAR(50),
    col_none VARCHAR(10),
    col_datetime VARCHAR(50)
"""

con = STPython.Connection('sysdba','szoscar55','localhost:2003/osrdb')
cursor = con.Cursor()
cursor.execute(csql)
bulk = STPython.Bulk(con,table_name, schema=schema, colsDesc=cols_desc, bufferSize=bufferSize)
col_str_data = "testInitBulkBySTpython_%d"
col_bytes_data = b'a'*300
data_rows = []
for i in range(2):
    data_row_tuple = (col_str_data %(i+1), col_bytes_data,i+1, i+0.23, [i+1,"collist"],
                    {"a":1,"b":2,"c":"c3"}, ("tuple_Val", "tuple_Val1"), "None", datetime.datetime.now())
    data_rows.append(data_row_tuple)
bulk.addrows(data_rows)
bulk.excute()
print("insert rows: " ,bulk.numRows)
print("bulk.buffSize: " ,bulk.buffSize)
print("bulk.colsDesc: " ,bulk.colsDesc)
print("bulk.schema: " ,bulk.schema)
bulk.close()

异常处理

STPython引发的所有异常都继承自 STPython.Error。应用程序可以根据需要捕获异常。例如,在尝试添加数据库中已存在的客户时,可以使用以下内容来捕获异常:

try:
    cursor.execute("insert into customer values (101, 'Customer A')")
except STPython.Error:
    print("insert data error")
else:
    print("Customer added")

事务管理

当 Cursor.execute() 执行 SQL 语句时,事务将启动或继续。默认情况下,STPython不将此事务提交到数据库。方法 Connection.commit() 和 Connection.rollback() 方法可用于显式提交或回滚事务:

try:
    connection.begin()
    cursor.execute("UPDATE TAB1 SET A = 1000,B = 'b2' WHERE A=1")
    1/0
    connection.commit()
except:
    connection.rollback()
cursor.close()
connection.close()

当数据库连接关闭时(例如使用 Connection.close() 时,或者当引用该连接的变量超出范围时,任何未提交的事务都将回滚。

自动提交

另一种提交方法是将连接的属性自动提交设置为 。这可确保在执行所有 DML 语句(INSERT、UPDATE 等)时都已提交。与Connection.commit()不同,这不需要额外的数据库往返,因此在适当使用时效率更高。 请注意,无论自动提交值如何,神通 数据库在执行 DDL 语句时将始终提交打开的事务。 当执行构成单个事务的多个 DML 语句时,建议仅对操作序列中的最后一个 DML 语句使用自动提交模式。不必要地提交会导致额外的数据库负载,并可能破坏事务一致性。

显式事务

方法 Connection.begin()可用于显式启动本地或全局事务。 如果没有参数,这将显式开始本地事务;否则,这将显式启动具有给定参数的分布式(全局)事务。 请注意,为了使用全局(分布式)事务,必须设置属性Connection.internal_name和Connection.external_name属性。

字符集

在STPython中,用于所有字符数据的默认编码更改为“UTF-8”。这种通用编码适用于大多数应用。如果您有特殊需要,可以将 和 参数传递给 STPython.connect() ,以指定不同的 神通 客户端字符集。

connection = STPython.connect(user="SYSDBA", password="szoscar55",
                            dsn="localhost:2003/osrdb", threaded = False,
                            encoding="UTF-8",events=True)

您可以使用环境变量来设置神通客户端库使用的语言和区域。例如,在 Linux 上,您可以设置:NLS_OSCAR_LANG

如:

export NLS_OSCAR_LANG=UTF-8