【问题标题】:ColdFusion Multiple cfif conditions only returns the 1st conditionColdFusion 多个 cfif 条件仅返回第一个条件
【发布时间】:2014-04-22 17:58:36
【问题描述】:

我是 ColdFusion 的新手,我必须创建一个编辑页面来更新和跟踪对表格所做的更改;同时将登录的 AD 用户传递给数据库。

Environment:
DB: SQL 2008 R2
OS: Windows 8
Server: ColdFusion 8

Tables Involved:
Branches (main data)
Audit_Branches (change tracking data)

Files involved:  
editBranch.cfm (form)
updateBranch.cfc (updates Branches table)
auditBranchLog.cfc (updates Audit_Branches table)

到目前为止,我已经构建了页面,并添加了更新分支表的功能。现在,我正在尝试跟踪更改并记录进行更改的 AD 用户。

我首先使用 SQL 触发器来监视 Branches 表上的插入、更新和删除;但 SQL Server 只跟踪当前 SQL 用户。由于该用户是应用程序用户,因此所有用户都具有相同的名称条目。因此,我重新设计了 Audit_Branches 表以通过 CF 直接插入数据,因此我可以传递 AD 用户名。

主要问题:我可以将三个字段中的第一个插入到 Audit_Branches 表中。如果多个字段发生更改,则仅运行 Arguments 数组中的第一个字段,而忽略其他字段。

我正在使用 cf-if 语句添加查询,然后通过 cf-invoke 将其传递给 auditBranchLog 函数。

我试过嵌套 if, if-else;和/或声明都无济于事。请帮我找出让 updateBranch 一个一个地遍历所有 ifs 的最佳方法,或者建议一种更好的方法将信息传递给 auditBranchLog

非常感谢...

------------------ 编辑分支代码:

 <cfquery name="getBranches" datasource=[...]>

    SELECT 
     BRANCHID,
     BRANCHDESCRIPTION,
     BRANCHFILTER,
     ADDRESS1,
[...]
FROM Branches
where BRANCHID = '#URL.BRANCHID#'
</cfquery>  

<script>

function updateBranch(){
var branchID = $('#branchID').val() ;   
var branchDescription = $('#branchDescription').val() ;
var branchDescription_Old = $('#branchDescription_Old').val() ;    
var branchFilter = $('#branchFilter').val(); 
var branchFilter_Old = $('#branchFilter_Old').val() ;     
var address1 = $('#address1').val(); 
var address1_Old = $('#address1_Old').val();
[...]


$.ajax(
    {
  // the location of the CFC to run
   url: "updateBranch.cfc"
  // send a GET HTTP operation
  , type: "get"
  // send the data to the CFC
  , data: {
    // the method in the CFC to run
      method: "UpdateBranches"
    // send the BranchID
    , branchID: branchID
    , branchDescription: branchDescription
    , branchDescription_Old: branchDescription_Old
    , branchFilter: branchFilter
    , branchFilter_Old: branchFilter_Old
    , address1: address1
    , address1_Old: address1_Old
[...]
            } 
  // this gets the data returned on success
  , success: function doLoad(data) {  if (typeof console != "undefined") { 
            console.log(data); 
        };  location.href = "BranchList.cfm";

                                   }

    } )
}



</script>

</head>

<body>

<cfoutput>

<form class="form-horizontal" action="" method="post">

[...]

<fieldset>


<!-- Form Name -->
<legend>Edit Branch</legend>

<!-- BRANCHID input-->
<div class="form-group">
  <label class="col-md-4 control-label" for="branchID">Branch ID</label>  
  <div class="col-md-4">
  <input id="branchID" class="form-control input-md" name="branchID" type="text" placeholder="" 
         value="#getBranches.BRANCHID#" readonly="yes">

  </div>
</div>

<!-- BRANCHDESCRIPTION input-->
<div class="form-group">
  <label class="col-md-4 control-label" for="branchDescription">Branch Description</label>  
  <div class="col-md-4">
  <input id="branchDescription" class="form-control input-md" name="branchDescription" 
         value="#getBranches.BRANCHDESCRIPTION#" type="text" placeholder="">

  <input id="branchDescription_Old" name="branchDescription_Old" value="#getBranches.BRANCHDESCRIPTION#"
         type="hidden">


  </div>
</div>

<!-- BRANCHFILTER input-->
<!--- using CFSelect allows to get the db field back for the current selection --->    
<div class="form-group">
  <label class="col-md-4 control-label" for="branchFilter">Branch Filter</label>  
  <div class="col-md-4">    
      <select id="branchFilter" class="form-control" name="branchFilter" size="1">
        <cfif LEN(getBranches.branchFilter) GT 0>
            <option value="#getBranches.branchFilter#" selected>#getBranches.branchFilter# (current value)</option>
            <option value="#getBranches.branchFilter#">---</option>            
        </cfif>
        <option value="Branch">Branch</option>
        <option value="Headquarters">Headquarters</option>
        <option value="RDC">RDC</option>
        <option value="Automation">Automation</option>
      </select>

      <input id="branchFilter_Old" name="branchFilter_Old" value="#getBranches.BRANCHFILTER#"
         type="hidden">


  </div>
</div>


<!-- ADDRESS1 input-->
<div class="form-group">
  <label class="col-md-4 control-label" for="address1">Address 1</label>  
  <div class="col-md-4">
  <input id="address1" class="form-control input-md" name="address1" type="text" 
         value="#getBranches.ADDRESS1#" placeholder="">


   <input id="address1_Old" name="address1_Old" value="#getBranches.ADDRESS1#"
         type="hidden">


  </div>
</div>

[...]

<!-- SUBMIT Button -->
<div class="form-group">
  <label class="col-md-4 control-label" for="SUBMIT"></label>
  <div class="col-md-4">
    <button type = "button" id="SUBMIT" class="btn btn-primary" name="SUBMIT" onClick="updateBranch()">Submit</button>

  </div>
</div>

------------------ 更新分支代码:

<cfcomponent displayname="Branches" access="remote" hint="Update Branches">

<cffunction name="getUserID" displayname="getUserID" hint="I pass back the user information in a clean format" access="package" output="false">
        <cfset var UserID = "">

        <cfset UserID = [...] >

        <cfreturn UserID>
</cffunction>     



<cffunction name="UpdateBranches" access="remote"  returntype="string"
    hint="Changes the Branch Info"  >

 <cfargument name="branchID" />

 <cfargument name="branchDescription" />
 <cfargument name="branchDescription_Old" />

 <cfargument name="branchFilter" />
 <cfargument name="branchFilter_Old" />

 <cfargument name="address1" />
 <cfargument name="address1_Old" />

  <cfset auditLog = QueryNew("BranchID,FieldName,Old,New,UserID", "VarChar, VarChar, VarChar, VarChar, VarChar")>     


 <!--- compare old a new and call auditBranchLog.cfc --->

 <!---BranchDescription--->
<cfif "#ARGUMENTS.branchDescription#" NEQ "#ARGUMENTS.branchDescription_Old#">
     <cfset newrow = QueryAddRow(auditLog)>
     <cfset temp = QuerySetCell(auditLog,"BranchID","#ARGUMENTS.branchID#")>
     <cfset temp = QuerySetCell(auditLog,"FieldName","BranchDescription")>
     <cfset temp = QuerySetCell(auditLog,"Old","#ARGUMENTS.branchDescription_Old#")>
     <cfset temp = QuerySetCell(auditLog,"New","#ARGUMENTS.branchDescription#")>
     <cfset temp = QuerySetCell(auditLog,"UserID","#getUserID()#")>
 </cfif>

 <!---BranchFilter--->  
 <cfif "#ARGUMENTS.branchFilter#" NEQ "#ARGUMENTS.branchFilter_Old#">
     <cfset newrow = QueryAddRow(auditLog)>
     <cfset temp = QuerySetCell(auditLog,"BranchID","#ARGUMENTS.branchID#")>
     <cfset temp = QuerySetCell(auditLog,"FieldName","BranchFilter")>
     <cfset temp = QuerySetCell(auditLog,"Old","#ARGUMENTS.branchFilter_Old#")>
     <cfset temp = QuerySetCell(auditLog,"New","#ARGUMENTS.branchFilter#")>
     <cfset temp = QuerySetCell(auditLog,"UserID","#getUserID()#")>
 </cfif>

 <!---Address1--->  
 <cfif "#ARGUMENTS.address1#" NEQ "#ARGUMENTS.address1_Old#">
     <cfset newrow = QueryAddRow(auditLog)>
     <cfset temp = QuerySetCell(auditLog,"BranchID","#ARGUMENTS.branchID#")>
     <cfset temp = QuerySetCell(auditLog,"FieldName","Address1")>
     <cfset temp = QuerySetCell(auditLog,"Old","#ARGUMENTS.address1_Old#")>
     <cfset temp = QuerySetCell(auditLog,"New","#ARGUMENTS.address1#")>
     <cfset temp = QuerySetCell(auditLog,"UserID","#getUserID()#")>         
 </cfif>


<cfif auditLog.RecordCount NEQ 0>
    <cfinvoke component="auditBranchLog" method="auditBranch" auditLog="#auditLog#" >
</cfif> 

<cfquery name=[...]
   </cfquery>


   <cfreturn arguments.branchID />


 </cffunction>
</cfcomponent>

------------------ 审计分支日志代码:

<cffunction name="auditBranch" displayname="auditBranch" >

    <cfargument name="auditLog" type="query" required="true">



        <cfquery name="auditBranchQry" datasource=[...]>

            USE [...]


            INSERT INTO [dbo].[Audit_BRANCHES]
           ([BranchID]
           ,[FieldName]
           ,[Old]
           ,[New]
           ,[ChangeDate]
           ,[UserID])

            VALUES
           (

            <CFQUERYPARAM CFSQLTYPE="CF_SQL_VARCHAR" VALUE="#auditLog.BranchID#" />
           ,<CFQUERYPARAM CFSQLTYPE="CF_SQL_VARCHAR" VALUE="#auditLog.FieldName#" />
           ,<CFQUERYPARAM CFSQLTYPE="CF_SQL_VARCHAR" VALUE="#auditLog.Old#" />
           ,<CFQUERYPARAM CFSQLTYPE="CF_SQL_VARCHAR" VALUE="#auditLog.New#" />
           ,getdate()
           ,<CFQUERYPARAM CFSQLTYPE="CF_SQL_VARCHAR" VALUE="#auditLog.UserID#" />

            )


        </cfquery>



        <cfset testVar = "true">

        <cfreturn testVar>


</cffunction> 
</cfcomponent>

更新:

这是来自 cfdump 的信息,我更改了所有三个值:

<th class="query" colspan="6" onClick="cfdump_toggleTable(this);" style="cursor:pointer;" title="click to collapse">query</th>
</tr>

<tr bgcolor="eeaaaa" >
<td class="query"   style="cursor:pointer;" title="click to collapse" onClick="cfdump_toggleRow_qry(this);">&nbsp;</td>

<td class="query">BRANCHID</td>

<td class="query">FIELDNAME</td>

<td class="query">NEW</td>

<td class="query">OLD</td>

<td class="query">USERID</td>

</tr>


<tr >
<td   style="cursor:pointer;" title="click to collapse" onClick="cfdump_toggleRow_qry(this);" class="query">1</td>


    <td valign="top">YYZ </td>

    <td valign="top">BranchDescription </td>

    <td valign="top">BranchLabel-New </td>

    <td valign="top">BranchLabel </td>

    <td valign="top">user.name </td>

</tr>

<tr >
<td   style="cursor:pointer;" title="click to collapse" onClick="cfdump_toggleRow_qry(this);" class="query">2</td>


    <td valign="top">YYZ </td>

    <td valign="top">BranchFilter </td>

    <td valign="top">Branch </td>

    <td valign="top">Headquarters </td>

    <td valign="top">user.name </td>

</tr>

<tr >
<td   style="cursor:pointer;" title="click to collapse" onClick="cfdump_toggleRow_qry(this);" class="query">3</td>


    <td valign="top">YYZ </td>

    <td valign="top">Address1 </td>

    <td valign="top">Address1-new </td>

    <td valign="top">Address1 </td>

    <td valign="top">user.name </td>

</tr>

</table>
<wddxPacket version='1.0'><header/><data><string>YYZ</string></data></wddxPacket> 

【问题讨论】:

  • &lt;cfif "#ARGUMENTS.branchFilter#" NEQ "#ARGUMENTS.branchFilter_Old#"&gt; -> &lt;cfif ARGUMENTS.branchFilter NEQ ARGUMENTS.branchFilter_Old&gt; 更好的是:&lt;cfif ARGUMENTS.branchFilter IS NOT ARGUMENTS.branchFilter_Old&gt; IS NOT 表示这是一个字符串比较; NEQ 表示数字比较。应该注意的是,这是为了语义让您和任何其他开发人员知道变量类型,因为运算符执行相同的功能。在任何情况下都不需要哈希标签和引号。

标签: sql if-statement coldfusion insert-update cfquery


【解决方案1】:

我从办公室里的一个同事那里发现了我做错了什么。

我只需要将 cfquery 包装在 cfoutput 标记中的 auditBranchLog 中,如下所示:

<cfoutput query="arguments.auditLog">

<cfquery name="auditBranchQry" datasource="[...]">
[...]
</cfquery>

</cfoutput>

这允许 ColdFusion 循环查询。

我觉得有点害羞。

感谢 James 的帮助,它确实让我看到了我正在寻找的答案之外的东西。

【讨论】:

  • 如果您不输出任何内容,您可以使用 cfloop 标签并将查询属性传递给循环。
【解决方案2】:

关于此代码

<!---BranchDescription--->
<cfif "#ARGUMENTS.branchDescription#" NEQ "#ARGUMENTS.branchDescription_Old#">
 <cfset newrow = QueryAddRow(auditLog)>
 <cfset temp = QuerySetCell(auditLog,"BranchID","#ARGUMENTS.branchID#")>
 <cfset temp = QuerySetCell(auditLog,"FieldName","BranchDescription")>
 <cfset temp = QuerySetCell(auditLog,"Old","#ARGUMENTS.branchDescription_Old#")>
 <cfset temp = QuerySetCell(auditLog,"New","#ARGUMENTS.branchDescription#")>
 <cfset temp = QuerySetCell(auditLog,"UserID","#getUserID()#")>
</cfif>


<!---Address1--->  
<cfif "#ARGUMENTS.address1#" NEQ "#ARGUMENTS.address1_Old#">
 <cfset newrow = QueryAddRow(auditLog)>
 <cfset temp = QuerySetCell(auditLog,"BranchID","#ARGUMENTS.branchID#")>
 <cfset temp = QuerySetCell(auditLog,"FieldName","Address1")>
 <cfset temp = QuerySetCell(auditLog,"Old","#ARGUMENTS.address1_Old#")>
 <cfset temp = QuerySetCell(auditLog,"New","#ARGUMENTS.address1#")>
 <cfset temp = QuerySetCell(auditLog,"UserID","#getUserID()#")>         
 </cfif>


<cfif auditLog.RecordCount NEQ 0>
    <cfinvoke component="auditBranchLog" method="auditBranch" auditLog="#auditLog#" >
</cfif> 

看起来您正在以某种 ORM 样式推送查询。

考虑一下会很有用

  1. &lt;cfdump var="#auditlog#"&gt;.
  2. 每个动作都有一个函数,而不是单个auditBranch
  3. 看到所有这些QuerySetCell() 让我觉得可能需要一种不同的方法。

更新

建议如下

<cfdump var="#auditlog#">


<cfif auditLog.RecordCount NEQ 0>
     <cfinvoke component="auditBranchLog" method="auditBranch" auditLog="#auditLog#" >
</cfif> 

【讨论】:

  • 我正在使用 但是,我没有收到任何信息。您通常如何显示来自 cfc 的信息?
  • 我很少使用&lt;cfinvoke&gt;。通常,当我创建一个对象时,我会为整个请求保留它。所以在我创建一个对象之后,我会做类似objAudit.auditBranch(auditLog);
  • 我找到了答案(见上文),但由于声誉太低而无法发布答案。谢谢詹姆斯的帮助,它确实让我看到了我正在寻找的答案之外。
  • @JohnySnow - AFAIK,应该允许所有用户发布 answer,无论声誉级别如何。系统可能会强制您等待几个小时才能关闭它,但您应该仍然可以发布它。
  • 谢谢@Leigh,这就是我的意思,但没有正确表达。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-19
相关资源
最近更新 更多