【问题标题】:cx_oracle python iterationcx_oracle python 迭代
【发布时间】:2018-05-22 06:48:59
【问题描述】:

我有我的 python 脚本,它逐行读取 excel 列并返回所有行 str(values)。 我想编写另一个脚本,允许将这些值放入 sql db。我已经写了connect方法:

def db_connect():
    adr = 'some_addr'
    uid = 'some_uid'
    pwd = 'pwd'
    port = port

    dsn_tns = cx_Oracle.makedsn(adr, port, SID)
    db = cx_Oracle.connect('username', 'pass', dsn_tns)

    cur = db.cursor()
    cur.execute('update TABLE set ROW = 666 where ANOTHER_ROW is null')
    db.commit()

此方法进行更新,但它为所有行设置了 666。如何通过sql中的迭代来做到这一点?比如第一行输出== 1,第二行== 23,第三行== 888。

【问题讨论】:

    标签: python sql database iteration cx-oracle


    【解决方案1】:

    如果我正确理解您在此处尝试执行的操作,则应分两个阶段完成。首先选择所有行进行更新(根据选择的条件),然后您可以迭代更新这些行中的每一行。

    它不能在单个查询中完成(或仅在多个查询中不会改变的单个条件),因为 SQL 在集合上工作,这就是为什么每次执行查询时都会更新整个表,并且在end 只获取最后一个查询的结果。

    【讨论】:

      【解决方案2】:

      您可以使用“rownum”表达式,如:

      cur.execute("update TABLE set ROW = rownum where ANOTHER_ROW is null")
      

      这将从值 1 开始,每更新一行就递增 1。

      如果您想对要设置的值进行更多控制,您还可以在 PL/SQL(未经测试)中执行以下操作:

      cur.execute("""
              declare
                  t_NewValue number;
                  cursor c_Data is
                      select ROW, ANOTHER_ROW
                      from TABLE
                      where ANOTHER_ROW is null
                      for update;
              begin
                  t_NewValue := 1;
                  for row in c_Data loop
                      update TABLE set ROW = t_NewValue
                      where current of c_Data;
      
                      t_NewValue := t_NewValue + 1;
                  end loop;
              end;""")
      

      这为您提供了最大的控制权。您可以使用所需的任何逻辑来控制新值应该是什么。

      【讨论】:

      • 当然可以,但这不是我想要实现的。请检查我的答案,我添加了更多代码。
      【解决方案3】:

      请查看另一种写入 excel 的方法:

      adr = 'some_addr'
      uid = 'some_uid'
      pwd = 'pwd'
      port = port
      
      dsn_tns = cx_Oracle.makedsn(adr, port, SID)
      db = cx_Oracle.connect('username', 'pass', dsn_tns)
      
      cur = db.cursor()
      
      cells = excel.read_from_cell()
      indices_and_statuses = []
      stat = execute_script(some_js)
      for req_id in cells:
          indices_and_statuses.append((cells.index(req_id), stat))
          cur.execute("""update TABLE set ROW ="""+"'"+req_id+"'"+"""where ANOTHER_ROW is null""")
          db.commit()
      db.close()
      

      并且在这段代码中,当您将 print(req_id) 放入此 FOR 语句时,您会看到 req_id 正在发生变化。但在 DB 中只保存了最后一个 req_id。

      【讨论】:

      • 这仅仅是因为您正在执行更新,更新每一行的次数与单元格的数量一样多!如果您想遍历行并同时更新,您将需要使用 PL/SQL 以避免不断地往返于数据库。如果您希望我相应地调整我的答案,请告诉我。
      • @AnthonyTuinga,你能给我举个例子吗?
      • 我添加了一个例子。
      猜你喜欢
      • 2020-01-02
      • 2010-09-05
      • 2011-02-27
      • 2022-01-21
      • 2015-01-10
      • 2017-02-16
      • 1970-01-01
      • 2013-05-09
      • 1970-01-01
      相关资源
      最近更新 更多