2014-02-12 52 views
1

去年,我發佈了一個問題here關於提交一個50字段的表單,以及最好的方法來做到這一點。該解決方案仍在使用中,運行良好。然而,爲了構建這些動態查詢,我最終得到了很多重複的<cfif>,我想知道是否有更好的方法來處理這個問題。雖然代碼結束了「雜亂」,但由於這一點,db當然非常乾淨,並且寫入次數也保持在最低限度,但有沒有更好的方法來執行以下操作?將大型表格保存到多個表格,規範化和動態查詢

<cfif StructKeyExists(arguments.form,"data1") or StructKeyExists(arguments.form,"data2") or StructKeyExists(arguments.form,"data3")> 
    <cfquery> 
    insert into table1 (
     <cfif StructKeyExists(arguments.form,"data1")>data1,</cfif> 
     <cfif StructKeyExists(arguments.form,"data2")>data2,</cfif> 
     <cfif StructKeyExists(arguments.form,"data3")>data3,</cfif> 
     userid 
    ) 
    values (
     <cfif StructKeyExists(arguments.form,"data1")><cfqueryparam cfsqltype="cf_sql_varchar" value="#arguments.form.data1#" maxlength="30">,</cfif> 
     <cfif StructKeyExists(arguments.form,"data2")><cfqueryparam cfsqltype="cf_sql_varchar" value="#arguments.form.data2#" maxlength="10">,</cfif> 
     <cfif StructKeyExists(arguments.form,"data3")><cfqueryparam cfsqltype="cf_sql_varchar" value="#arguments.form.data3#" maxlength="25">,</cfif> 
     <cfqueryparam cfsqltype="cf_sql_smallint" value="#arguments.form.userid#" maxlength="5"> 
    ) 
    on duplicate key update 
     <cfif StructKeyExists(arguments.form,"data1")>data1=values(data1),</cfif> 
     <cfif StructKeyExists(arguments.form,"data2")>data2=values(data2),</cfif> 
     <cfif StructKeyExists(arguments.form,"data3")>data3=values(data3),</cfif> 
     userid=values(userid) 
    </cfquery> 
</cfif> 

這種'感覺'出於某種原因是錯誤的。難道例如更加聰明,能,而有更多的寫操作,每個值分割到自己的更新,就像這樣:

<cfif StructKeyExists(arguments.form,"data1")> 
    <cfquery> 
    insert into table1 (data1,userid) 
    values (<cfqueryparam cfsqltype="cf_sql_varchar" value="#arguments.form.data1#" maxlength="30">,<cfqueryparam cfsqltype="cf_sql_smallint" value="#arguments.form.userid#" maxlength="5">) 
    on duplicate key update data1=values(data1),userid=values(userid) 
    </cfquery> 
</cfif> 

還是有更好的方式來做到這一點,我完全可以俯瞰?!

回答

0

如果你知道你有多達50個字段,並且它們的名字都是一致的(data1 ... dataN),我只需要一個循環。例如:

<cfloop index="i" from="1" to="50"> 
    <cfif StructKeyExists(arguments.form, "data#i#")> 
     <cfquery> 
      insert into table1 (data#i#,userid) 
      values (<cfqueryparam cfsqltype="cf_sql_varchar" value="#arguments.form['data' & i]#" maxlength="30">,<cfqueryparam cfsqltype="cf_sql_smallint" value="#arguments.form.userid#" maxlength="5">) 
      on duplicate key update data#i#=values(data#i#),userid=values(userid) 
     </cfquery> 
    </cfif> 
</cfloop> 
+0

對不起,我本來應該更清晰,但它不是很*是*一致。我重寫了這個問題的命名,但它更像arguments.form.departure_date/arguments.form.staffid/arguments.form.otherinfo等。我可以循環arguments.form我假設,但值進入不同的表( staffid進入表2,其他信息進入表3等),並且沒有自動的方式知道哪個值在哪個表中。 – sckd

+2

_「有沒有自動的方式知道」_ - 所以使用手動方式;每個表都有一個數組,它可以接收可能的字段,並循環這些數據。 –

+0

好吧,我循環遍歷arguments.form,然後使用一堆包含每個表的字段以及cfqueryparam的sql類型和maxlength的數組來匹配更新的字段,然後對每個更改執行一次插入/更新?這肯定會讓代碼更加乾淨!因此,就我原來的問題而言,在一次寫入可能包含多個值的情況下,最終還會產生大量單寫操作?感謝所有的建議;絕對在這裏學習很多! – sckd

0

是的,還有一種更好的方法來做到這一點,無論如何,我認爲。

首先,不是檢查是否存在所有50個字段,只是檢查表單是否已提交。一旦你完成了,唯一可能不存在的字段是複選框和單選按鈕。

接下來,在進入cfquery標籤之前先完成所有的條件邏輯。除複選框和單選按鈕之外,您不檢查是否存在某個值,而是檢查有效性。如果需要表單字段,請確保它不是空字符串。另外請確保您具有數字和日期字段的正確數據類型。

在此階段,您可能需要設置一些用於cfqueryparam的null屬性的變量。例如,如果您有一個可選的數字字段並且用戶沒有填寫它,則需要一個等於true的變量,以便數據庫接收一個空值。空字符串僅適用於文本字段。

另請注意,數據的質量比代碼的外觀更重要。儘管可讀代碼很重要,但您不會在10行或更少的代碼中處理50個表單域。

+1

我確定已經在代碼的這個階段之前檢查了很久,如果表單被提交,必填字段等。關鍵是我不想最終寫入空行到表中,因爲這基本上破壞了規範化的點(可能每個人都有一行)。這是在構建動態插入/更新查詢的過程中,我認爲事情必須能夠得到改進,至少可讀性和可擴展性是明智的。 – sckd

+0

_「如果需要表單字段,請確保它不是空字符串。」_ - 空字符串和沒有值是兩個不同的東西。 –

+0

*如果表單已提交,已經在代碼的這個階段之前檢查了很長時間,所需的字段在那裏*正確,但我認爲想法是將驗證(服務器端)與查詢邏輯分開,以便當您運行SQL,你已經消除了「空行」的可能性。然後,查詢代碼只是插入任何給定的數據,因爲該數據已經過驗證。當然,有時你可以乾淨地同時做兩個 - 但根據你原來的問題,我不確定你的表結構是否適合這種情況。 – Leigh

0

我覺得你這樣做的方式很好。

我不會將你的插入/更新分解爲每個數據字段的單獨查詢。當提交很多字段時,這會導致更多的開銷。想象一下,所有50個表單域都被提交了,50個查詢,yike。

如果需要處理空值,這裏有辦法把你的語法內做到這一點的例子:

<cfif structKeyExists(arguments.form, "data1"><cfqueryparam value="#arguments.form.data1#" null="#(NOT len(arguments.form.data1))#" cfsqltype="cf_sql_integer">,</cfif> 
+0

我認爲你是對的,這可以歸結爲可能提交多少字段的決定。從我所看到的情況來看,它似乎主要是2,3,4個字段,如果可以像Peter建議的那樣自動完成,那麼可能需要更新每個數據字段設置的一個查詢。如果沒有,我會保持原樣,因爲如果許多字段一次更新,當前的解決方案會更好。 – sckd