【发布时间】: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);"> </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>
【问题讨论】:
-
<cfif "#ARGUMENTS.branchFilter#" NEQ "#ARGUMENTS.branchFilter_Old#">-><cfif ARGUMENTS.branchFilter NEQ ARGUMENTS.branchFilter_Old>更好的是:<cfif ARGUMENTS.branchFilter IS NOT ARGUMENTS.branchFilter_Old>IS NOT表示这是一个字符串比较;NEQ表示数字比较。应该注意的是,这是为了语义让您和任何其他开发人员知道变量类型,因为运算符执行相同的功能。在任何情况下都不需要哈希标签和引号。
标签: sql if-statement coldfusion insert-update cfquery