通过PyRFC调用RFC_READ_TABLE中的开放SQL条件
我该如何在使用PyRFC的RFC_READ_TABLE查询中指定Open SQL的WHERE子句?
我正在尝试使用PyRFC,让Python从SAP中提取表格数据(因为没有支持或合作的基础团队)。在这个来自http://scn.sap.com/community/scripting-languages/blog/2012/11/04/revisiting-python-and-sap-with-pyrfc的例子中,他们使用了:
pyrfc.Connector.call("RFC_READ_TABLE", QUERY_TABLE=table, DELIMITER='|')
http://saplsmw.com/node/101提到需要将WHERE子句作为OPTION传递给RFC调用。我该如何在PyRFC中做到这一点?(OPTIONS是RFC_READ_TABLE函数模块声明中的一个导出变量,类型为表格,在SAP端使用)。
编辑:好的,http://scn.sap.com/community/scripting-languages/blog/2014/05/05/python-for-basis有一个关于如何在OPTIONS中发送WHERE子句的例子:
OPTIONS = [{'TEXT':source_where}])
看起来语法是一个数组(映射SAP表类型),里面是单元素字典,字典的键是SAP数据类型,值是WHERE子句。
接下来的问题是:我该如何指定一个PACKAGE SIZE,发送给RFC_READ_TABLE,以便我可以提取大表而不触及内部表的限制?
1 个回答
RFC_READ_TABLE 有一个参数叫 'ROWCOUNT',它用来指定一次最多返回多少行数据。
当然,如果你限制每次只取 1000 行,而表里有超过 1000 行的数据,那么有些数据你就永远取不到了。
为了解决这个问题,还有一个参数叫 'ROWSKIPS',通过这个参数你可以指定从哪一行开始取数据。
所以,第一次调用的时候可以这样设置:
ROWCOUNT = 1000
ROWSKIPS = 0
接下来第二次调用:
ROWCOUNT = 1000
ROWSKIPS = 1000
再接下来第三次调用:
ROWCOUNT = 1000
ROWSKIPS = 2000
以此类推,每次调用的时候都把 ROWSKIPS 增加 1000,变成:ROWSKIPS = ROWSKIPS + ROWCOUNT。
下面是一个使用 PyRFC 的例子,里面同时定义了 ROWCOUNT 和 ROWSKIPS,读取 TCURR 表的数据,每次取 10 行(并且 FCURR 设置为 'USD'):
#!/usr/bin/env python
from pyrfc import Connection, ABAPApplicationError, ABAPRuntimeError, LogonError, CommunicationError
from ConfigParser import ConfigParser
from pprint import PrettyPrinter
def main():
try:
config = ConfigParser()
config.read('sapnwrfc.cfg')
params_connection = config._sections['connection']
conn = Connection(**params_connection)
options = [{ 'TEXT': "FCURR = 'USD'"}]
pp = PrettyPrinter(indent=4)
ROWS_AT_A_TIME = 10
rowskips = 0
while True:
print u"----Begin of Batch---"
result = conn.call('RFC_READ_TABLE', \
QUERY_TABLE = 'TCURR', \
OPTIONS = options, \
ROWSKIPS = rowskips, ROWCOUNT = ROWS_AT_A_TIME)
pp.pprint(result['DATA'])
rowskips += ROWS_AT_A_TIME
if len(result['DATA']) < ROWS_AT_A_TIME:
break
except CommunicationError:
print u"Could not connect to server."
raise
except LogonError:
print u"Could not log in. Wrong credentials?"
raise
except (ABAPApplicationError, ABAPRuntimeError):
print u"An error occurred."
raise
if __name__ == '__main__':
main()