使用cx_Oracle和python在查询中通过字典和List传递值有什么区别?

时间:2013-05-03 12:18:15

标签: python oracle

以下查询正常工作(通过字典传递值)

cursor.execute("""insert into MDP_ERR_MASTER (MARKERID, FILENAME, ERRORCODE, USERID, CHECKEDBY, CHECKEDDT, STATUS, COMMENTS, X1, Y1, Z1, X2, Y2, Z2, RECNO, PROJECT_CODE, SRC_ACC_NUM, WORKAREA, CONFIGID, ELEMENTID)
            values (:markerid,:shapename,:errcode,'0',:sysid,sysdate,'OPEN',:usercomment,:x1,:y1,0,:x2,:y2,0,1,:jobno,:srcacnum,chr(182) || :workarea || chr(182),0,0)""",
            {"markerid" : markerId,
             "shapename" : str(errorMarkerLayer.name()),
             "errcode" : errCode ,
             "sysid" : self.sysid ,
             "usercomment" : str(comments),
             "x1" : startPnt[0],
             "y1" : startPnt[1],
             "x2" : endPnt[0],
             "y2" : endPnt[1],
             "jobno" : self.jobNo,
             "srcacnum" : src_AcNum,
             "workarea" : self.wrkArea
             })

但是下面的列表传递值不能正常工作'Variable_TypeByValue():未处理的数据类型元组'

cursor.execute("""insert into MDP_ERR_MASTER (MARKERID, FILENAME, ERRORCODE, USERID, CHECKEDBY, CHECKEDDT, STATUS, COMMENTS, X1, Y1, Z1, X2, Y2, Z2, RECNO, PROJECT_CODE, SRC_ACC_NUM, WORKAREA, CONFIGID, ELEMENTID)
            values (:1,:2,:3,'0',:4,sysdate,'OPEN',:5,:6,:7,0,:8,:9,0,1,:10,:11,chr(182) || :12 || chr(182),0,0)""",
            [(1 , markerId),
             (2 , str(errorMarkerLayer.name())),
             (3 , errCode),
             (4 , self.sysid),
             (5 , str(comments)),
             (6 , startPnt[0]),
             (7, startPnt[1]),
             (8 , endPnt[0]),
             (9, endPnt[1]),
             (10 , self.jobNo),
             (11 , src_AcNum),
             (12 , self.wrkArea)
             ]) 

2 个答案:

答案 0 :(得分:1)

当您提供列表时,参数将根据列表中的位置包含在查询中,而不是通过查找键。因此,对于第一个值,(1, markedId)代替markerId

虽然元组列表可以很容易地转换为字典,但它不是相同的数据结构。首先使用dict()将参数转换为字典。

cursor.execute("""insert into MDP_ERR_MASTER (MARKERID, FILENAME, ERRORCODE, USERID, CHECKEDBY, CHECKEDDT, STATUS, COMMENTS, X1, Y1, Z1, X2, Y2, Z2, RECNO, PROJECT_CODE, SRC_ACC_NUM, WORKAREA, CONFIGID, ELEMENTID)
            values (:1,:2,:3,'0',:4,sysdate,'OPEN',:5,:6,:7,0,:8,:9,0,1,:10,:11,chr(182) || :12 || chr(182),0,0)""",
            dict([(1 , markerId),
             (2 , str(errorMarkerLayer.name())),
             (3 , errCode),
             (4 , self.sysid),
             (5 , str(comments)),
             (6 , startPnt[0]),
             (7, startPnt[1]),
             (8 , endPnt[0]),
             (9, endPnt[1]),
             (10 , self.jobNo),
             (11 , src_AcNum),
             (12 , self.wrkArea)
             ])) 

如果您使用的是cx_Oracle,请参阅here了解文档。

答案 1 :(得分:0)

在列表(第二个代码示例)中,您仍然具有“命名”参数。而不是像“:markerid”这样的好名字,你有“:1”。我相信你在使用命名参数时必须使用字典。

如果您需要使用数字命名参数,只需使用数字键名称构建字典。

如果你只是需要位置替换,那么我相信“?”可能支持语法,但我不建议使用“?”语法,因为它很难维护,你必须在输入中多次指定相同的值。

另一种选择是使用pythons字符串格式/替换运算符“%”,这意味着您在查询执行之前处理参数替换。