2016-05-24 8 views
1

私は私のプロジェクトでDBの値と.csvファイルの値を比較しなければならないところに取り組んでいます。 'cfhttp'を使用して.csvをクエリに変換した後、そのクエリとDBから値を取得するために使用した別のクエリをループします。これら2つのループの中でif文を使って値を比較し、一致するかどうかを調べました。次に、それらをリストに格納し、それらのリストをcfqueryタグで使用して更新しました。 DBには14kレコード、.csvファイルには同数のレコードがあります。私の現在のコードは、テスト目的のために、リストから画面にレコードを出力するのに2分以下しかかかりません。私はまだ更新がどれくらいかかるかテストしなかった。アップデートを実行する前に、私のプロジェクトに他のアプローチをお勧めする人がいたら見たいですか?実行時間を現在の時間よりも短くすることはできますか?ここで私が持っている私のコードは次のとおりです。2つの別々のquiresの値を比較する方法はありますが、内部ループは使用しませんか?

ここ
<cfhttp name="records" columns="A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X" method="get" url="http://path to csv/temp.csv"/> 

<cfquery name="getRecords" datasource="test"> 
    Select s.ID, f.URID, s.UR_NUMBER, CODE, f.FIELD 
    From USERS s 
    Left Outer Join MAPS f 
    ON s.ID = f.URID 
</cfquery> 

<cfset NumA = ""> 
<cfset NumB = ""> 
<cfset NumC = ""> 

<cfset NumD = ""> 
<cfset NumE = ""> 
<cfset updNumD = ""> 
<cfset updNumE = ""> 

<cfloop query="records"> 
    <cfloop query="getRecords"> 
     <cfif records.A EQ getRecords.UR_NUMBER> 
      <cfif records.W NEQ getRecords.CODE> 
       <cfif records.W EQ 'A'> 
        <cfset NumA = ListAppend(NumA,"#records.A#")> 
       <cfelseif records.W EQ 'B'> 
        <cfset NumB = ListAppend(NumB,"#records.A#")> 
       <cfelse> 
        <cfset NumC = ListAppend(NumC,"#records.A#")> 
       </cfif> 
      </cfif> 

      <cfif getRecords.URID EQ ''> 
       <cfif records.W EQ 'D'> 
        <cfset NumD = ListAppend(NumD, "#getRecords.ID#")> 
       <cfelseif records.W EQ 'E'> 
        <cfset NumE = ListAppend(NumE, "#getRecords.ID#")> 
       </cfif> 
      <cfelse> 
       <cfif records.W EQ 'E'> 
        <cfset updNumD = ListAppend(updNumD, "#getRecords.URID#")> 
       <cfelseif records.W EQ 'D'> 
        <cfset updNumE = ListAppend(updNumE, "#getRecords.URID#")> 
       </cfif> 
      </cfif> 
     </cfif> 
    </cfloop> 
</cfloop> 

私は画面に私のリストをダンプ:それはcfhttpタグと私はから必要なだけの列を取得することが可能です場合

<cfdump var="#NumA#"> 
<cfdump var="#NumB#"> 
<cfdump var="#NumC#"> 
<br> 
<cfdump var="#NumE#"> 
<cfdump var="#NumD#"> 
<br> 
<cfdump var="#updNumE#"> 
<cfdump var="#updNumD#"> 

はまた、私は思っていました私の.csv?今私は自分の.csvからすべてのカラムをガービングしていますが、カラムAとWのうちの2つだけを使用しても、'cfhttp'からDBからのクエリにクエリを結合することは可能ですか?誰かが私にこのプロジェクトに関するアドバイスをくれれば教えてください。

+0

cflib.orgには2つの機能があります。 ListCompareは、1つのリスト内にあるものとそうでないものを示します。 ListAndは両方のリストにあるものを示します。 14 Kのレコードでは、これはおそらくクエリのクエリよりも優れたアプローチです。 –

+0

'listAppend()'の代わりに 'arrayAppend()'を使って処理を大幅に高速化する必要があります。リストとして出力する必要がある場合は 'arrayToList()'を使うことができます。基本的に引用符を使用している場所でも引用符をドロップすることができます。なぜ ""#getRecords.ID# "'は 'getRecords.ID'になります –

+0

@MattBuscheなぜ私は最初に配列に格納し、それをリストに変換しますか?それは私のページの全体的なプロセスに時間がかかります。また、特定のフィールドの更新を実行するだけでWHERE句に配置できるので、リストを使用しています。 –

答えて

2

records.AgetRecords.UR_NUMBERのデータにのみ興味があると思います。クエリのクエリを使用して、2つのデータセットの共通部分を取得できます。次のようなものがあります:

<cfquery name="intersection" dbtype="query"> 
    select * 
    from records, getRecords 
    where records.A = getRecords.UR_NUMBER 
</cfquery> 

これで、ループしてリストを構築できる結合データセットが得られるはずです。 Matt Buscheがコメントで述べたように、リスト操作は遅いので、arrayAppendは高速になります。

クエリまたはクエリが遅すぎる場合は、ルックアップが高速であるため、レコードセットの1つを構造体(キー値ペア)に変換することができます。例:

<cfscript> 
// convert to structs as key lookups are fast 
dbData = {}; 
for (row in getRecords) { 
    dbData[row.UR_NUMBER] = row; 
} 

csvData = {}; 
for (row in records) { 
    if (structKeyExists(dbData, row.A)) { 
     // we have a match, so build the lists here... 
     writeDump(dbData[row.A]); 
    } 
} 
</cfscript> 
+0

質問のクエリについて質問があります。以前はそれらを使用していなかったので、cfqueryタグでデータソースに使うべきものを混乱させましたか? .csvファイルは2番目のクエリで私のレコードを引っ張っている同じDBから来ていないので。上の例では、dbtypeの「クエリ」があります。自分のコードで同じことを使うことはできますか?手伝ってくれてありがとう。 –

+0

また、このエラーが発生しました:=実行中の比較例外。 互換性のない型の比較例外:コンパレータ演算子 "="の左辺と右辺に互換性のない型があります。 左辺式type = "VARCHAR"です。 右辺式のタイプ= "DOUBLE"。 –

+0

あなたが14000の代わりに14のレコードを扱っていたなら、これは良い答えでしょう。 –

関連する問題