2016-03-02 63 views
2

我有一個動態表單,有多個複選框,並提交我想運行一個CFSTOREDPROC在另一個cfloop只使用改變狀態的複選框值。Coldfusion從動態表單複選框創建數組

到目前爲止,下面是一個粗略的概念,我試圖測試,但我確信我創建我的數組的方式會有問題。如果任何人都可以提供可能的解決方案的反饋,我會感激。

HTML/CF FORM:

<form action="self.cfm" method="post" name="permissions"> 
<input type="hidden" name="User_ID" value="<CFOUTPUT>#User_ID#</CFOUTPUT>"> 
<table> 
<CFLOOP QUERY="getNthPermission"> 
<tr><td>#getNthPermission.Permission_Name#</td><td><input type="checkbox" value="#getNthPermission.Permission_ID#" name="#getNthPermission.Permission_Name#" <CFIF LISTVALUECOUNT(VARIABLES.UserPermission_ID_List,getNthPermission.Permission_ID) NEQ 0>CHECKED</CFIF>></td></tr> 
</CFLOOP> 
</table> 
<input type="submit" name="submit" value="Update"> 
</form> 

COLDFUSION ACTION:

<CFSET VARIABLES.Permission_ID_List = ValueList(getUserPermission.Permission_ID)> 
    <cfset changed_permissions=ArrayNew()> 
    <CFLOOP QUERY="getNthPermission"> 
    //If it was checked when the form was created but was unchecked by the user add it to my array. 
    <CFIF LISTVALUECOUNT(VARIABLES.UserPermission_ID_List,getNthPermission.Permission_ID) NEQ 0 AND !IsDefined(FORM.#getNthPermission.Permission_Name#)> 
    <cfset changed_permissions[getNthPermission.Permission_ID]> 
    <CFELSEIF LISTVALUECOUNT(VARIABLES.UserPermission_ID_List,getNthPermission.Permission_ID) EQ 0 AND IsDefined(FORM.#getNthPermission.Permission_Name#)> 
    //If it wasn't checked when the form was built but was checked by the user add it to my array. 
    <cfset changed_permissions[getNthPermission.Permission_ID]> 
    </CFIF> 
    </CFLOOP> 

通過剛創建並通過存儲過程我的值的陣列//現在環路

<CFLOOP from="1" to="#arrayLen(changed_permissions)#" index="i"> 
    <CFSTOREDPROC DATASOURCE="#MYDB_DSN#" PROCEDURE="Update_UserPermission"> 
     <CFPROCPARAM DBVARNAME="@PermissionList" VALUE="#changed_permissions[i]#" TYPE="IN" CFSQLTYPE="cf_sql_longvarchar"> 
     <CFPROCPARAM DBVARNAME="@User_ID" VALUE="#FORM.User_ID#" CFSQLTYPE="cf_sql_integer"> 
    </CFSTOREDPROC> 
</CFLOOP> 

更新:

我正與一個數據庫配置工作,我是不設立,其中有這些表的一部分:

  • 權限表(PERMISSION_NAME,ID) - 權限名單
  • 用戶表(USER_NAME ,ID)
  • User_Permissions表(Permissions_ID,User_ID) - 包含用戶有權訪問的每個權限的條目。

因此,作爲複選框被選中/未選中我需要添加新條目或刪除一個。哪一個已經存在的存儲過程(或者我希望它存在)。

+1

它只是一組可以分配/取消分配給單個用戶的權限嗎?如果沒有涉及到實際值的樣本,那麼很難直觀地看到*精確*關係。另外,這些權限如何存儲在數據庫中,單獨的行或作爲csv列表(希望不是)? – Leigh

+0

不幸的是,我正在使用一個數據庫配置,而我並不是設置的一部分。有一個包含權限列表(permission_name,ID)和用戶表(user_name,ID)和User_Permissions表(Permissions_ID,User_ID)的表,其中包含用戶有權訪問的每個權限的條目。所以當複選框被選中/取消選中時,我可以添加一個新條目或刪除一個。哪一個已經存在的存儲過程(或者我希望它) – Denoteone

回答

3

三張桌子是一個很好的設置。我擔心這是一個單獨的表格,或者這些值被存儲爲csv列表{顫抖}。仍然不能很好地形象化你的表單,但是從你描述的內容來看,聽起來像用幾個查詢來做這件事會更簡單,而不是循環。

首先,給複選框相同的名稱,如「Permission_IDList」,這樣的ID將被作爲一份名單。然後使用的ID的該列表與下列選項之一:

選項1:刪除/插入ALL

的一種方法,我經常用簡單的junction tables做法是先刪除所有現有的用戶權限。然後使用INSERT/SELECT插入新的權限。使用INSERT的兩個大的優勢/ SELECT是它省去了循環,並且還提供了內置的驗證。

這是最簡單的一個選項,而是因爲它會刪除所有記錄,每次它並不像選擇2那樣精確。因此從技術上講,它可能會比許多情況下需要做的工作多一點。雖然除非你處理大量記錄,差異通常可以忽略不計。沿着這些線路(未測試)的東西:

--- First remove all existing permissions for User 
    DELETE FROM User_Permissions 
    WHERE User_ID = <cfqueryparam value="#FORM.User_ID#" cfsqltype="cf_sql_integer"> 

    --- Now re-insert current/new permissions 
    INSERT INTO User_Permissions (User_ID, Permissions_ID) 
    SELECT u.ID AS User_ID 
      , p.ID AS Permissions_ID 
    FROM UserTable u CROSS JOIN PermissionTable p 
    WHERE u.ID = <cfqueryparam value="#FORM.User_ID#" cfsqltype="cf_sql_integer"> 
    AND  p.ID IN 
      (
       <cfqueryparam value="#FORM.Permission_IDList#" cfsqltype="cf_sql_integer" list="true"> 
      ) 

選項2:刪除改變/ INSERT加入

另一種選擇是使用查詢來識別和DELETE卸下的權限,即,未選中。然後使用INSERT/SELECT插入添加的權限。其餘的保持不變。它比選項1複雜一點,但更精確的是,它只刪除或添加實際改變的內容。同樣,沒有測試,但是這樣的事情:

--- existing id's NOT in the new list were UN-checked 
    DELETE FROM User_Permissions 
    WHERE User_ID = <cfqueryparam value="#FORM.User_ID#" cfsqltype="cf_sql_integer"> 
    AND Permissions_ID NOT IN 
      (
       <cfqueryparam value="#FORM.Permission_IDList#" cfsqltype="cf_sql_integer" list="true"> 
      ) 


    INSERT INTO UserPermissions (User_ID, Permissions_ID) 
    SELECT u.ID AS User_ID 
      , p.ID AS Permissions_ID 
    FROM UserTable u 
       CROSS JOIN PermissionsTable p 
       LEFT JOIN UserPermissions up ON up.User_ID = u.ID AND up.Permissions_ID = p.ID 
    --- this user + permission does not already exist 
    WHERE up.Permissions_ID IS NULL   
    AND u.ID = <cfqueryparam value="#FORM.User_ID#" cfsqltype="cf_sql_integer"> 
    AND p.ID IN 
     (
        <cfqueryparam value="#FORM.Permission_IDList#" cfsqltype="cf_sql_integer" list="true"> 

     ) 

NB:一定要在一個事務來包裝這兩個查詢,以便它們作爲一個單元,即兩個都成功,要麼都失敗處理。

+0

再次感謝Leigh提供的詳細解決方案。兩者都很合理,說實話,我很高興擺脫循環。我將選擇#1,因爲我們只談論少數權限,我並不擔心影響性能。這是你今天幫助我的第二個節日。再次感謝! +1檢查。 – Denoteone

+0

我對第一個選項如何通過每個權限運行沒有使用循環有疑問嗎?上述SQL是否被用作存儲過程?感謝您的跟進.. – Denoteone

+0

等待幾遍代碼後,我看到這將如何工作。我現在會測試並讓你知道結果。再次感謝。 – Denoteone