0

データベースから質問を取得する調査用の関数を作成しようとしています。キャッチは、アクティブな質問と非アクティブな質問の両方があるということです。誰かが古い調査の結果を表示したときに表示される古い質問が必要です。

これが私がCFC内で試しているコードです:

<cffunction name="getAllQuestions" access="public" returntype="query">
    <cfargument name="survey" default=0>
    <cfif len(#survey#) gt 0>
    <cfquery name="getsdate" datasource="blah.database">
    select * from past_survey
    where survey_id = #survey#
    </cfquery>
    <cfreturn getsdate>
    </cfif>
    <cfquery name="getquestions" datasource="blah.database">
        select * from pool_questions
        <cfif len(#survey#) eq 0> 
        where active_flag='Y'
        <cfelse>
        where <cfqueryparam value="#dateformat 
                       (getsdate.survey_date, "yyyy/mm/dd")#"> BETWEEN start_date AND  
                       end_date
        </cfif>   
        order by qtn_nb
    </cfquery>
    <cfreturn getquestions>
</cffunction>

#survey#フォームによって生成される調査IDです。私がやろうとしているsurveyのは、クエリgetsdateを実行する値がある場合です。次に、値があるかどうかに関係なく、2番目のクエリが実行されますsurvey。価値がない場合は、すべてのアクティブな質問をプルする必要があります。値がある場合は、調査日が過去の質問の開始日と終了日の間にあるかどうかを確認する必要があります。

この作業を行う方法についてのアドバイスをいただければ幸いです。前もって感謝します!

4

2 に答える 2

4
    <cffunction name="getAllQuestions" access="public" returntype="struct">
        <cfargument name="survey" required="true" default="0" type="numeric">

        <cfset var qryReturn                    = ""> <!---Always var scope your variables to prevent them from leaking to other functions --->
        <cfset var structReturn                 = structNew()>
        <cfset structReturn.pastSurvey          = "">
        <cfset structReturn.surveyQuestions     = "">

        <cfif survey GT 0>
            <cfquery name="qryReturn" datasource="blah.database">
                SELECT * 
                FROM   past_survey
                <!--- Always cfqueryparam to prevent SQL injection attacks & also always reference the scope to prevent confusion --->
                WHERE  survey_id = <cfqueryparam cfsqltype="cf_sql_integer" value="#arguments.survey#">
            </cfquery>
            <cfset structReturn.pastSurvey = qryReturn>
       <cfelse>
            <cfquery name="qryReturn" datasource="blah.database">
                 SELECT *
                 FROM pool_questions
                 <cfif arguments.survey EQ 0>
                     WHERE active_flag = 'Y'
                 <cfelse>
                     WHERE <cfqueryparam value="#dateformat 
                       (getsdate.survey_date, "yyyy/mm/dd")#"> BETWEEN start_date AND  
                       end_date
                 </cfif>
                 ORDER BY qtn_nb
             </cfquery>
             <cfset structReturn.surveyQuestions = qryReturn>
        </cfif>

        <cfreturn structReturn>
    </cffunction> 

あなたはおそらくこれを2つの別々の機能で行うべきですが、私はあなたの質問に答えようとします。

私のコードは、過去の調査と調査の質問を返すクエリの構造体を返します(必要に応じて配列に変更できます)。

注:サンプルコードには、いくつかの悪い習慣があります。

  1. 値自体をチェックするのではなく、調査値の長さをチェックしています。
  2. 合格したかどうかに関係なく、アンケートに常に値を設定requried=trueする場合は、デフォルト値を設定して指定します。
  3. cfqueryparamSQLインジェクション攻撃を防ぐために使用
  4. 関数で作成された変数varは、同じcfcomponent内の他のcffunctionにリークしないようにスコープを設定する必要があります。私はいつも一番上でこれをします。はい、cfqueryに付ける名前でさえ、varスコープにする必要があります。
  5. 最初のクエリの後にリターンを実行しているため、調査値が0より大きい場合、日付チェックがある2番目のクエリに到達することはありません。
于 2013-01-16T18:23:11.677 に答える
1

対処する必要のある次の問題があります。

まず、調査引数のデフォルト値は0であり、その長さに対して条件付きロジックを実行しています。「0」の長さは1であるため、条件は常にtrueを返します。

次に、最初のクエリが実行されるかどうかに関係なく、2番目のクエリを実行することを指定しますが、2番目のクエリの最初のクエリの値を参照します。つまり、最初のクエリが実行されない場合、未定義の変数が原因で2番目のクエリがクラッシュします。

次に、dateformatは文字列を返します。2番目のクエリで行う方法で適用することは、せいぜい不要であり、最悪の場合、開始日と終了日を文字列としてpool_questionsに格納していることを示します。最初のクエリで日付フィールドの時間部分を削除しようとしている場合、ColdFusionにはそのためのcast()関数があります。

また、変数のスコープを設定します。つまり、の代わりに<cfif len(survey)、これを実行します<cfif len(arguments.survey)

また、ローカル変数をvarします。この場合、それは2つのクエリの名前です。

それはあなたが始めるはずです。

于 2013-01-16T18:24:02.817 に答える