检索Oracle DB 12c中最近插入的标识

dsekswqp  于 2022-11-22  发布在  Oracle
关注(0)|答案(5)|浏览(114)

我希望通过python中的cx_oracle将为我插入的行创建的Identity的值返回给我。如果有人能说明如何修改我的SQL语句以获得新创建的行的ID,我想我可以自己弄清楚python位。
我创建了一个表,它的内容如下所示:

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版和更低版本的,它们不支持自动生成的标识列,所以希望这里有人能帮忙。

pgccezyw

pgccezyw1#

根据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()
6ioyuze2

6ioyuze22#

这个 取自 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 } 的 缺失

dddzy1tm

dddzy1tm3#

使用insert陈述式的传回子句。

insert into hypervisor (name ) values ('my hypervisor')
 returning id into :python_var

你说你能处理Python的部分?你应该能在你的程序中“绑定”返回参数。

bmp9r5qi

bmp9r5qi4#

我喜欢Marco波罗的答案,但它是不完整的。FelDev的答案也很好,但没有解决命名参数。下面是一个更完整的例子,来自我用简化表(更少的字段)编写的代码。我省略了如何设置游标的代码,因为在其他地方有很好的文档。

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))
ajsxfq5m

ajsxfq5m5#

同意以前的答案。但是,根据您的cx_Oracle版本(7.0和更高版本),var.getvalue()可能返回数组而不是标量。这是为了支持本注解中所述的多个返回值。
另请注意,cx_Oracle已过时,现在已迁移到oracledb
示例:

newId = cur.var(oracledb.NUMBER, outconverter=int)
sql = """insert into Locations(latitude, longitude) values (:latitude, :longitude) returning locationId into :newId"""
sqlParam = [latitude, longitude, newId]
cur.execute(sql, sqlParam)
newIdValue = newId.getvalue()

newIdValue将返回[1]而不是1

相关问题