检索 Oracle DB 12c 中最近插入的标识
Retrieving identity of most recent insert in Oracle DB 12c
我想返回给我(通过 python 中的 cx_oracle)为我插入的行创建的身份的值。我想我可以自己弄清楚 python 位,如果有人可以说明如何修改我的 SQL 语句以获取新创建的行的 ID。
我有一个 table 是用如下内容创建的:
CREATE TABLE hypervisor
(
id NUMBER GENERATED BY DEFAULT AS IDENTITY (
START WITH 1 NOCACHE ORDER ) NOT NULL ,
name VARCHAR2 (50)
)
LOGGING ;
ALTER TABLE hypervisor ADD CONSTRAINT hypervisor_PK PRIMARY KEY ( id ) ;
我有 SQL 类似于以下内容:
insert into hypervisor ( name ) values ('my hypervisor')
有没有简单的方法获取新插入行的id
?如果可能的话,我很乐意修改我的 SQL 语句以将其返回。
关于此问题的大多数 google 命中都是针对版本 11 及以下版本,它们不支持自动生成的标识列,因此希望这里有人可以提供帮助。
使用插入语句的 returning 子句。
insert into hypervisor (name ) values ('my hypervisor')
returning id into :python_var
你说你可以处理 Python 位?您应该能够 "bind" 程序中的 return 参数。
采用上面 user2502422 所说的内容并添加 python 位:
newest_id_wrapper = cursor.var(cx_Oracle.STRING)
sql_params = { "newest_id_sql_param" : newest_id_wrapper }
sql = "insert into hypervisor ( name ) values ('my hypervisor') " + \
"returning id into :python_var"
cursor.execute(sql, sql_params)
newest_id=newest_id_wrapper.getvalue()
这个取自 learncodeshare.net 的例子帮助我掌握了正确的语法。
cur = con.cursor()
new_id = cur.var(cx_Oracle.NUMBER)
statement = 'insert into cx_people(name, age, notes) values (:1, :2, :3) returning id into :4'
cur.execute(statement, ('Sandy', 31, 'I like horses', new_id))
sandy_id = new_id.getvalue()
pet_statement = 'insert into cx_pets (name, owner, type) values (:1, :2, :3)'
cur.execute(pet_statement, ('Big Red', sandy_id, 'horse'))
con.commit()
它与 ragerdl 的回答仅略有不同,但我相信足以添加到这里!
注意缺少 sql_params = { "newest_id_sql_param" : newest_id_wrapper }
我喜欢马可波罗的回答,但不完整。
FelDev 的回答也很好,但没有解决命名参数问题。
这是我用简化的 table (较少字段)编写的代码中的一个更完整的示例。我省略了有关如何设置游标的代码,因为其他地方对此有详细记录。
import cx_Oracle
INSERT_A_LOG = '''INSERT INTO A_LOG(A_KEY, REGION, DIR_NAME, FILENAME)
VALUES(A_KEY_Sequence.nextval, :REGION, :DIR_NAME, :FILENAME)
RETURNING A_KEY INTO :A_LOG_ID'''
CURSOR = None
class DataProcessor(Process):
# Other code for setting up connection to DB and storing it in CURSOR
def save_log_entry(self, row):
global CURSOR
# Oracle variable to hold value of last insert
log_var = CURSOR.var(cx_Oracle.NUMBER)
row['A_LOG_ID'] = log_var
row['REGION'] = 'R7' # Other entries set elsewhere
try:
# This will fail unless row.keys() =
# ['REGION', 'DIR_NAME', 'FILE_NAME', 'A_LOG_ID']
CURSOR.execute(INSERT_A_LOG, row)
except Exception as e:
row['REJCTN_CD'] = 'InsertFailed'
raise
# Get last inserted ID from Oracle for update
self.last_log_id = log_var.getvalue()
print('Insert id was {}'.format(self.last_log_id))
我想返回给我(通过 python 中的 cx_oracle)为我插入的行创建的身份的值。我想我可以自己弄清楚 python 位,如果有人可以说明如何修改我的 SQL 语句以获取新创建的行的 ID。
我有一个 table 是用如下内容创建的:
CREATE TABLE hypervisor
(
id NUMBER GENERATED BY DEFAULT AS IDENTITY (
START WITH 1 NOCACHE ORDER ) NOT NULL ,
name VARCHAR2 (50)
)
LOGGING ;
ALTER TABLE hypervisor ADD CONSTRAINT hypervisor_PK PRIMARY KEY ( id ) ;
我有 SQL 类似于以下内容:
insert into hypervisor ( name ) values ('my hypervisor')
有没有简单的方法获取新插入行的id
?如果可能的话,我很乐意修改我的 SQL 语句以将其返回。
关于此问题的大多数 google 命中都是针对版本 11 及以下版本,它们不支持自动生成的标识列,因此希望这里有人可以提供帮助。
使用插入语句的 returning 子句。
insert into hypervisor (name ) values ('my hypervisor')
returning id into :python_var
你说你可以处理 Python 位?您应该能够 "bind" 程序中的 return 参数。
采用上面 user2502422 所说的内容并添加 python 位:
newest_id_wrapper = cursor.var(cx_Oracle.STRING)
sql_params = { "newest_id_sql_param" : newest_id_wrapper }
sql = "insert into hypervisor ( name ) values ('my hypervisor') " + \
"returning id into :python_var"
cursor.execute(sql, sql_params)
newest_id=newest_id_wrapper.getvalue()
这个取自 learncodeshare.net 的例子帮助我掌握了正确的语法。
cur = con.cursor()
new_id = cur.var(cx_Oracle.NUMBER)
statement = 'insert into cx_people(name, age, notes) values (:1, :2, :3) returning id into :4'
cur.execute(statement, ('Sandy', 31, 'I like horses', new_id))
sandy_id = new_id.getvalue()
pet_statement = 'insert into cx_pets (name, owner, type) values (:1, :2, :3)'
cur.execute(pet_statement, ('Big Red', sandy_id, 'horse'))
con.commit()
它与 ragerdl 的回答仅略有不同,但我相信足以添加到这里!
注意缺少 sql_params = { "newest_id_sql_param" : newest_id_wrapper }
我喜欢马可波罗的回答,但不完整。 FelDev 的回答也很好,但没有解决命名参数问题。 这是我用简化的 table (较少字段)编写的代码中的一个更完整的示例。我省略了有关如何设置游标的代码,因为其他地方对此有详细记录。
import cx_Oracle
INSERT_A_LOG = '''INSERT INTO A_LOG(A_KEY, REGION, DIR_NAME, FILENAME)
VALUES(A_KEY_Sequence.nextval, :REGION, :DIR_NAME, :FILENAME)
RETURNING A_KEY INTO :A_LOG_ID'''
CURSOR = None
class DataProcessor(Process):
# Other code for setting up connection to DB and storing it in CURSOR
def save_log_entry(self, row):
global CURSOR
# Oracle variable to hold value of last insert
log_var = CURSOR.var(cx_Oracle.NUMBER)
row['A_LOG_ID'] = log_var
row['REGION'] = 'R7' # Other entries set elsewhere
try:
# This will fail unless row.keys() =
# ['REGION', 'DIR_NAME', 'FILE_NAME', 'A_LOG_ID']
CURSOR.execute(INSERT_A_LOG, row)
except Exception as e:
row['REJCTN_CD'] = 'InsertFailed'
raise
# Get last inserted ID from Oracle for update
self.last_log_id = log_var.getvalue()
print('Insert id was {}'.format(self.last_log_id))