我们需要创建几个SQL报告,每个报告都取决于上一个报告的结果。所有查询均采用以下形式: 选择1, 报告1, 从Select 1中选择2, 报告2, 从Select 2中选择3, 报告3, ...等等...... 报告N。
现在“N”个单独的SQL查询用于生成完整的报告集。每个查询都包含所有先前查询的SQL代码 - 这导致报告1完成“N”次,报告2完成“N - 1”次,等等。导致多个报告中相同选择语句的无意义重复导致性能问题。
我们如何将中间报告(最好是.csv文件)导出为报告“N”生成的报告,从而消除了对所有其他报告的需求?
一些特定于我们案例的复杂因素:
答案 0 :(得分:0)
以下是我自己的问题的完整解决方案(本来可以更好地称为“需要从SQL查询脚本导出多个结果”)。
另见这个使用相同通用方法的问题,除了它使用硬编码的SQL字符串 - 而fetchall()而不是fetchone():
<http://stackoverflow.com/questions/273203/access-second-result-set-of-stored-procedure-with-sql-or-other-work-around-pyth?rq=1>
以及:
<http://stackoverflow.com/questions/7263781/pyodbc-return-multiple-cursors-from-stored-procedure-with-db2>
仔细研究(继承的)SQL代码的许多行显示中间报告未被保存。只返回了最后一个SQL select / report的结果(到python)。
解决方案的SQL端包括创建用于保存结果集(报告)的新表,然后在SQL代码的最后返回所有结果集。
SQL代码现在看起来像:
SET NOCOUNT ON -- required by pyobdc (and other OBDC packages?) at start of code
SET @year = ? -- get OBDC (python) parameter 1
SET @month = ? -- get parameter 2
SET @day = ? -- get parameter 3
DECLARE @ReportX TABLE -- a new table, one of these for each report
-- Repeated for each report (1 to N):
INSERT INTO @ReportX -- NEW LINE, it preserves the report
SELECT ..... -- the original report, uses the passed-in parameters
-- At the very bottom of the SQL code, add one of these lines for each report:
Select * from @ReportX -- where X is 1 to N
解决方案的Python 3.x方面如下:
import pyodbc # contains cursor.execute, the interface to SQL
import csv # creates csv.writer, used to create the CSV file
Textfile = open( "FileContainingSqlCode", 'r' )
SQL_COMMANDS = Textfile.read(); # Get SQL code for all reports
cursor.execute( SQL_COMMANDS, Year, Month, Day ) # do all reports using 3 parameters
# Create first report from the first result set
ReportID = 1
filename = "D:\\Report" + str( ReportID ) + ".csv"
OutFile = open( filename, 'w', newline= '' )
Results = csv.writer( OutFile, delimiter = ',', quotechar = '"',
quoting = csv.QUOTE_MINIMAL )
while True:
row = cursor.fetchone()
if not row:
break
Results.writerow( row )
OutFile.close()
# Create the 2nd through Nth reports
while ( cursor.nextset() ) :
ReportID += 1
filename = "D:\\Report" + str( ReportID ) + ".csv"
OutFile = open( filename, 'w', newline= '' )
Results = csv.writer( OutFile, delimiter = ',', quotechar = '"',
quoting = csv.QUOTE_MINIMAL )
while True:
row = cursor.fetchone()
if not row:
break
Results.writerow( row )
OutFile.close()
# end of Python 3.x code
通过使用第二个while循环中的while(while(?? in cursor.nextset()),可以删除第一个报告部分。