1

複数のSQLレポートを作成する必要があります。各レポートは、前のレポートの結果に依存します。すべてのクエリの形式は次のとおりです。Select1、Report 1、Select 2 from Select 1、Report 2、Select 3 from Select 2、Report 3、...などから...ReportN。

現在、「N」個の個別のSQLクエリを使用して、レポートの完全なセットを生成しています。すべてのクエリには、以前のすべてのクエリのSQLコードが含まれています。その結果、レポート1は「N」回実行され、レポート2は「N​​-1」回実行されます。複数のレポートで同じselectステートメントが無意識に繰り返されると、パフォーマンスの問題。

レポート「N」によって生成される中間レポート(理想的には.csvファイル)をエクスポートして、他のすべてのレポートが不要になるようにするにはどうすればよいですか。


私たちのケースに固有のいくつかの複雑な要因:

  • ターンキーアプローチを使用する必要があり、手動による介入を使用するアプローチは受け入れられません。プレーンテキスト出力が必要です。
  • OBDC(具体的にはPythonのpyobdcパッケージ)は、SQLクエリをSQL Serverに(カーソルとして)渡すために使用されます。Pythonは結果を使用して、レポートを.csvファイルとして作成します。
  • ストアドSQLプロシージャは禁止されていますが、既存のSQLコードは一時テーブルを使用します。
  • 結果は私の(クライアント)マシンに書き込む必要があります。IM部門では、サーバー上の一時フォルダーの使用を許可している場合があります
  • pyobdcは1つの結果セットしか受け入れられないようです(したがって、「N」クエリが必要です)。適切な結果セットが返されるようにするには、SQLクエリが「SETNOCOUNTON」で始まる必要があります(pyobdcメーリングリストのアドバイスに従います)。SQLによって返される複数の結果セットから正しい結果セットを返す/選択する他の方法を私は知りません。結果セットをスキップするためにpyobdcメソッド(cursor.nextset)を試しましたが、何も返されませんでした。
  • レポート「n-1」の結果をレポート「N」に渡すことを検討しましたが、関連するデータの量が多分これを非現実的にしています。
  • Python(3.2.2)とSQLコードは、十分に証明された製品コードです。言語を変更することは実際的な選択肢ではありません。OBDCパッケージの変更は可能ですが、可能性は低いです(非常に強力なケースを作成する必要があり、他のOBDCパッケージはプラットフォーム間で簡単に移植でき、Microsoft SQL Server 2008 Management Studioに接続できる必要があります)。
  • pydevプラグインを備えたEclipse(Helios)を使用して、SQLクエリを起動するPythonアプリケーションを起動しています。
  • クライアントのO/SはXPProSp 3であり、サーバーは同じであると考えられています。同社は、マシンを「近いうちに」Windows 7/8に移行することを計画しているため、そのO/Sへの移植性が要因になります。
4

1 に答える 1

2

以下は、私自身の質問に対する完全な解決策です(「SQLクエリスクリプトから複数の結果をエクスポートする必要がある」というタイトルの方が適切です)。

ハードコードされたSQL文字列を使用することを除いて同じ一般的なアプローチを使用するこの質問も参照してください-そしてfetchone()の代わりにfetchall()-またその質問


(継承された)SQLコードの多くの行を詳しく見ると、中間レポートが保存されていないことがわかりました。最後のSQL選択/レポートの結果のみが(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 

ソリューションのPython3.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

最初のレポートセクションを削除するには、2番目のwhileループで:while(cursor.nextset()の??)の行に沿って何かを使用する必要があります。

于 2012-06-27T15:21:32.790 に答える