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。然后无论是否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> 

您可能应该在两个单独的函数中执行此操作,但我会尝试回答您的问题。

我的代码将返回一个查询结构(如果您愿意,您可以更改为一个数组),它返回一个过去的调查和调查问题

注意:在您的示例代码中,您有一些不好的做法。

  1. 您正在检查调查值的长度,而不是检查值本身。
  2. 如果要确保无论是否通过,调查始终具有值,请设置requried=true并赋予其默认值。
  3. 用于cfqueryparam防止sql注入攻击
  4. 在函数中创建的任何变量都需要var限定范围,以防止它们泄漏到同一 cfcomponent 中的其他 cffunctions。我总是在顶部这样做。是的,即使您给 cfquery 提供的名称也需要 var 作用域。
  5. 由于您在第一次查询后进行返回,因此如果调查值大于 0,它将永远不会到达进行日期检查的第二次查询。
于 2013-01-16T18:23:11.677 回答
1

我看到您需要解决以下问题。

首先,您的调查参数的默认值为 0,并且您正在对其长度进行条件逻辑。“0”的长度为 1,因此该条件将始终返回 true。

接下来,您声明无论第一个查询是否运行,您都希望第二个查询运行,但您在第二个查询中引用来自第一个查询的值。这意味着如果第一个查询没有运行,第二个查询将由于未定义的变量而崩溃。

接下来,dateformat 返回一个字符串。以您在第二个查询中的方式应用它充其量是不必要的,更糟糕​​的是,它表明您将开始和结束日期存储在 pool_questions 中作为字符串。如果您试图在第一个查询中去除日期字段的时间部分,ColdFusion 有一个 cast() 函数。

此外,确定变量的范围。即-而不是<cfif len(survey),这样做<cfif len(arguments.survey)

另外,var 你的局部变量。在这种情况下,它是您的两个查询的名称。

那应该让你开始。

于 2013-01-16T18:24:02.817 回答