使用绑定变量

在神通 数据库之间传递数据的 SQL 和 PL/SQL 语句应在 SQL 和 PL/SQL 语句中使用占位符,以标记提供或返回数据的位置。这些占位符称为绑定变量或绑定参数,绑定变量是以冒号为前缀的标识符或数字。例如,此 SQL 语句中有两个绑定变量:

cursor.execute("insert into MyTab values (:a, :b)", ["aaaa",16])

使用绑定变量对于可伸缩性和安全性非常重要。它们有助于避免 SQL 注入安全问题,因为数据永远不会被视为可执行语句的一部分。切勿将用户数据连接或插值到 SQL 语句中:

did = 280dnm = "Facility"
# !! Never do this !!
sql = f"""insert into departments (department_id, department_name)  values ({did}, '{dnm}')"""
cursor.execute(sql)

绑定变量可降低使用不同数据值多次执行语句时的解析和执行成本。如果不使用绑定变量,神通 必须重新分析和缓存多个语句。使用绑定变量时,神通 数据库可能能够重用语句执行计划和上下文。 绑定变量可用于替换数据,但不能用于替换语句的文本。例如,不能使用需要列名或表名的绑定变量。绑定变量也不能在数据定义语言 (DDL) 语句中使用,如 CREATE TABLE 或 ALTER 语句。

按名称绑定

可以按名称或位置完成绑定。当语句中的绑定变量与名称相关联时,将执行命名绑定。例如:

cursor.execute("insert into MyTab values (:a, :b)", a="aaa",b=16)

data = dict(a="aaa", b=16)
cursor.execute("insert into MyTab values (:a, :b)", data)

在上面的示例中,关键字参数名称或字典的键必须与绑定变量名称匹配。这种方法的优点是绑定变量在语句中的位置并不重要,名称可以是有意义的,并且可以重复名称,同时仍然只提供一次值。

按位置绑定

当绑定值列表传递给 execute() 调用时,将执行位置绑定。例如:

cursor.execute("insert into MyTab values (:a, :b)", ["aaaa",16])

请注意,对于 SQL 语句,绑定值的顺序必须与每个绑定变量的顺序完全匹配,并且重复的名称必须重复其值。但是,对于 PL/SQL 语句,绑定值的顺序必须与 PL/SQL 块中找到的每个唯一绑定变量的顺序完全匹配,并且值不应重复。为了避免这种差异,当绑定变量名称重复时,建议按名称绑定。

绑定方向

调用方可以向数据库 (IN) 提供数据,数据库可以向调用方 (OUT) 返回数据,或者调用方可以向数据库提供初始数据,数据库可以将修改后的数据提供回调用方 (IN/OUT)。这称为绑定方向。 上面显示的示例已将所有数据提供给数据库,因此被归类为 IN 绑定变量。为了让数据库向调用方返回数据,必须创建一个变量。这是通过调用方法 Cursor.var()来完成的,该方法标识将在该绑定变量中找到的数据类型及其最大大小等。

绑定空值

神通数据库允许直接绑定None,如:

cursor.execute("insert into MyTab values (:a, :b)", [None,19])

Out参数绑定

当 RETURN 子句与 DML 语句(如 UPDATE、INSERT 或 DELETE)一起使用时,值将通过使用 OUT 绑定变量返回到应用程序。请考虑以下示例:

b = cursor.var(int)

cursor.execute("""
        update mytab set
            a = :updateData
        where a = :beforeA
        returning b into :afterB""",
        updateData="update column", beforeA="ddd", afterB=b)
connection.commit()
print(b.getvalue())