2011-08-23 81 views
0

我們有一個通過表單元素動態循環的腳本,併爲我們的PostgreSQL數據庫創建一條INSERT語句。我從字段值轉義所有單引號,但查詢本身仍然失敗。但是,如果我直接在pgAdmin中運行查詢,它的工作原理!我失去了爲什麼。Coldfusion SQL錯誤

<cfset queryfields = "--already defined--"> 
<cfset queryvalues = "" /> 
<cfloop list="#fieldList#" delimiters="," index="f"> 
<cfif StructKeyExists(form, f)> 
<cfset queryvalues = queryvalues & "'" & Replace(form[f], "'", "\'", "all") & "'," /> 
</cfif> 
</cfloop> 
<!--- Remove trailing commma ---> 
<cfset queryvalues = Left(queryvalues, len(queryvalues) - 1) /> 

<cftransaction> 
<cfquery name="qInsertOrder" datasource="#DSN#"> 
INSERT INTO foo_trans (#queryfields#) 
VALUES(#queryvalues#) 
</cfquery> 
</cftransaction> 

INSERT INTO paypal_trans(TransDate,mc_gross,address_status,payer_id,稅務,address_street,PAYMENT_STATUS,字符集address_zip,如first_name)VALUES('08/22/2011' , '50.00', '確認', 'ABCD4321','0.00','1 Main Road','Completed','windows-1252','10505','Bob O'Malley')-------------- ---------------錯誤執行數據庫查詢。 (錯誤:在語法錯誤或接近 「08」)

回答

3

(ERROR: syntax error at or near "08")

在像你這樣的情況下,CF會自動地加倍(轉義)單引號以幫助防止sql注入。所以發送到數據庫的最後一個VALUES子句實際上更像這樣。注意每個單引號都翻倍了?

VALUES(''08/22/2011'', .. 

如果確實是這個問題,PreserveSingleQuotes()會修復它。但是,它也會顛倒CF的自動sql注入保護。既然你將所有的值都作爲字符串處理,你可以嘗試使用cfqueryparam來代替。你不會在類型檢查方面受到太多影響。但是您仍然可以動態地循環訪問這些字段,同時保持SQL注入保護。可能也會提升性能。

UPDATE:同樣使用cfqueryparam,您不必擔心手動轉義單引號。

UPDATE:要使用cfqueryparam,通過數組填充到insert.Then環路現有油田的陣列來生成VALUES條款。我做了一些假設,但這應該會產生預期的結果。

<!--- determine the fields to insert ---> 
<cfset fieldArray = arrayNew(1)> 
<cfloop list="#fieldList#" delimiters="," index="f"> 
<cfif StructKeyExists(form, f)> 
    <cfset arrayAppend(fieldArray, f)> 
</cfif> 
</cfloop> 


... 
<!--- loop through array to generate VALUES clause ---> 
VALUES 
(
<cfloop from="1" to="#arrayLen(fieldArray)#" index="x"> 
    <!--- append separator when needed ---> 
    <cfif x gt 1>,</cfif> 
    <cfqueryparam value="#FORM[fieldArray[x]]#" cfsqltype="cf_sql_varchar"> 
</cfloop> 
) 
+0

問題是我無法輸入查詢的各個字段和變量,原因是我不會介入。否則,我會立即使用'cfqueryparam',而沒有這個問題。 –

+0

你應該不需要。只需將所有內容都設置爲cf_sql_varchar即可。你失去了類型檢查,但這基本上就是你現在正在做的事情。除此之外,這個概念是一樣的。請給我一分鐘來展示一個例子。 – Leigh

+0

查看我的更新回覆。 – Leigh

3
+1

它確實有效。但它也打開了更多的SQL注入查詢。所以如果可能的話,用'cfqueryparam'代替。 – Leigh

+0

'PreserveSingleQuotes()'使用單引號留下var值,並且它導致SQL崩潰都一樣。 –

+0

@Angry - Re:*「使用單引號使var值保持轉義*」您*通過轉義意味着什麼? 'PreserveSingleQuotes'只是防止CF在事後自動加倍單引號。您仍然需要負責構建正確轉義的SQL字符串。你的新SQL字符串是否在pgAdmin中運行? – Leigh

0

什麼是列 「TransDate」 的數據類型?數據類型轉換可能存在問題?