2014-03-18 43 views
0

這是我的提交頁面,用於在博客中插入新帖子。ColdFusion解決多對多關係

第一個將Title,BlogBody和UserID插入到數據庫中。

第二部分是爲了插入用戶爲博客選擇的標籤,並通過聯結表將它們關聯到博客。 基本上,如果用戶選擇多個標籤,那麼每個標籤將成爲聯結表中的單獨條目,並且將在插入新博客帖子時與在自動遞增字段中創建的BlogID匹配。

目前此代碼可正確插入博客。如果同一個標題不使用兩次(因爲WHERE Title = '#Form.Title#'),我只選擇1個標籤,它也會進行正確的第2部分。

如何更改此代碼以允許多個標籤在聯結表中具有多個條目,以及如何將其更改爲無法獲得異常情況的地方,即用戶給出兩個博客的標題相同。

對於異常部分,我試過SELECT (Max)BlogID FROM BlogPosts,但是我得到了從「複雜到簡單的錯誤」的轉換。

我很清楚Microsoft Access不是一個好用的數據庫,但這是我不得不使用的。

<cfquery name="AddBlog" datasource="prpblog"> 
    INSERT INTO BlogPosts (Title, BlogBody, UserID) 
    VALUES 
    (
     <cfqueryparam value='#Form.Title#' cfsqltype="cf_sql_varchar"/>, 
     <cfqueryparam value='#Form.BlogBody#' cfsqltype="cf_sql_varchar"/>, 
     <cfqueryparam value='#Form.SelectAuthor#' cfsqltype="cf_sql_numeric"/> 
    ) 
</cfquery> 

<!--- Query to find BlogID from newest post ---> 
<CFQUERY name="BlogID" datasource="prpblog"> 
SELECT BlogID 
FROM BlogPosts 
WHERE Title = '#Form.Title#' 
</CFQUERY>      

<!--- Query to Insert BlogID/TagID into Junction Table ---> 
<cfquery name="AddTag" datasource="prpblog"> 
    INSERT INTO BlogTagJunction (BlogID,TagID, TagReal) 
    VALUES 
    (
     <Cfoutput query="BlogID">#BlogID#</cfoutput>, 
     <cfqueryparam value='#Form.SelectTag#' cfsqltype="cf_sql_numeric" />, 
     <cfqueryparam value='#Form.SelectTag#' cfsqltype="cf_sql_varchar" /> 


    ) 
</cfquery> 

(更新已刪除的答案)

這是我寫的基於關閉從您提供的網絡鏈接(忽略交易CF現在)提示的代碼。我收到:

執行數據庫查詢時出錯。 [Macromedia] [SequeLink JDBC 驅動程序] [ODBC套接字] [Microsoft] [ODBC Microsoft Access驅動程序]數據 類型在條件表達式中不匹配。

我刪除了「Select Statement」來幫助診斷問題。我仍然收到相同的錯誤。只用代碼中的頂級語句,我將createUUID()更改爲SubID()並接收:變量SUBID未定義,這是我的預期。但我現在明白了要做什麼。

<!--- Query to Insert Blog ---> 
<cfset variables.SubID=createUUID()> 
     <cfquery name="AddBlog" datasource="blog"> 
      INSERT INTO BlogPosts (
       Title, 
       BlogBody, 
       UserID, 
       SubID 
      ) 
      VALUES (
       <cfqueryparam value='#Form.Title#' cfsqltype="cf_sql_varchar"/>, 
       <cfqueryparam value='#Form.BlogBody#' cfsqltype="cf_sql_varchar"/>, 
       <cfqueryparam value='#Form.SelectAuthor#' cfsqltype="cf_sql_numeric"/>, 
       '#variables.SubID#' 
      ) 
     </cfquery> 
     <cfquery 
    name="getMyID" 
    datasource="blog"> 
    SELECT 
     BlogPosts.BlogID 
    FROM 
     BlogPosts 
    WHERE 
     BlogPosts.SubID = '#variables.SubID#' 
</cfquery> 

@Leigh

這是我寫的基於關閉從您提供的網絡鏈接(忽略交易CF現在)

我收到提示代碼: 錯誤執行數據庫查詢。 [Macromedia] [SequeLink JDBC驅動程序] [ODBC套接字] [Microsoft] [ODBC Microsoft Access驅動程序]標準表達式中的數據類型不匹配。

我刪除了「Select Statement」來幫助診斷問題。我仍然收到相同的錯誤。 只用代碼中的頂部語句,我將createUUID()更改爲SubID()並收到:變量SUBID未定義,這是我的預期。但我現在明白了要做什麼。

<!--- Query to Insert Blog ---> 
<cfset variables.SubID=createUUID()> 
     <cfquery name="AddBlog" datasource="blog"> 
      INSERT INTO BlogPosts (
       Title, 
       BlogBody, 
       UserID, 
       SubID 
      ) 
      VALUES (
       <cfqueryparam value='#Form.Title#' cfsqltype="cf_sql_varchar"/>, 
       <cfqueryparam value='#Form.BlogBody#' cfsqltype="cf_sql_varchar"/>, 
       <cfqueryparam value='#Form.SelectAuthor#' cfsqltype="cf_sql_numeric"/>, 
       '#variables.SubID#' 
      ) 
     </cfquery> 
     <cfquery 
    name="getMyID" 
    datasource="blog"> 
    SELECT 
     BlogPosts.BlogID 
    FROM 
     BlogPosts 
    WHERE 
     BlogPosts.SubID = '#variables.SubID#' 
</cfquery> 

編輯: 這是我從其他職位解釋:我結束了一個 Invalid data @@Identity for CFSQLTYPE CF_SQL_INTEGER.錯誤。

<cfquery name="AddTag" datasource="prpblog"> INSERT INTO BlogTagJunction (BlogID, TagID) SELECT <cfqueryparam value="@@Identity as Key" cfsqltype="cf_sql_integer">, TagID FROM Tags WHERE TagID IN ( <cfqueryparam value="#Form.SelectTag#" list="true" cfsqltype="cf_sql_numeric"/> ) </cfquery>

+0

我建議重讀[您的其他線程(http://stackoverflow.com/questions/22465173/inserting-information-into-a-junction-table-cold-fusion)和引用的鏈接。它解釋瞭如何做到這一點A)使用MS Access獲取新的ID'@@ IDENTITY - NB:這些語句必須包含在'cftransaction'中。 B)使用INSERT/SELECT結構,並結合來檢索並插入選定的標籤。注意,不需要在你的cfquery中使用cfoutput。簡單的'#變量#'會自動評估。如果您有具體問題,請先嚐試並回傳。 – Leigh

+0

您是否試過'SELECT Max(BlogID)'? –

+1

* SELECT Max(BlogID)*不要在Web應用中使用'max'方法。它是**不是線程安全的** – Leigh

回答

0

從其他線程:

「我通過了,抓住從我剛剛創建的博客的博客ID的博客插入語句後,給查詢語句來解決自己的問題。 「

在接受的答案中,用戶使用CFQUERY的內置變量「IDENTITYCOL」來獲取新ID的值。你不能用MS Access做到這一點。相反,您需要在一筆交易中進行3次查詢:

<cftransaction action="begin"> 

    <cftry> 

     <cfquery name="AddBlog" datasource="prpblog"> 
      INSERT INTO BlogPosts (
       Title, 
       BlogBody, 
       UserID 
      ) 
      VALUES (
       <cfqueryparam value='#Form.Title#' cfsqltype="cf_sql_varchar"/>, 
       <cfqueryparam value='#Form.BlogBody#' cfsqltype="cf_sql_varchar"/>, 
       <cfqueryparam value='#Form.SelectAuthor#' cfsqltype="cf_sql_numeric"/> 
      ) 
     </cfquery> 

     <!--- Query to find BlogID from newest post ---> 
     <cfquery name="BlogID" datasource="prpblog"> 
      SELECT @@IDENTITY AS NEW_ID 
     </cfquery> 

     <!--- Query to Insert BlogID/TagID into Junction Table ---> 
     <cfquery name="AddTag" datasource="prpblog"> 
      INSERT INTO BlogTagJunction (
       BlogID, 
       TagID, 
       TagReal 
      ) 
      VALUES (
       <cfqueryparam value='#BlogID.NEW_ID#' cfsqltype="cf_sql_numeric" />, 
       <cfqueryparam value='#Form.SelectTag#' cfsqltype="cf_sql_numeric" />, 
       <cfqueryparam value='#Form.SelectTag#' cfsqltype="cf_sql_varchar" /> 
      ) 
     </cfquery> 

    <cfcatch type="database"> 

     <cftransaction action="rollback"> 

    </cfcatch> 

    </cftry> 

    <cftransaction action="commit"> 

</cftransaction>

希望這會有所幫助。

UPDATE:Here's why you should not use SELECT MAX(ID) to get a newly inserted ID.

+0

我認爲數據庫異常是在'cftransaction'內自動回滾? – Henry

+0

並非總是如此。如果你的數據庫被配置爲自動提交一個事務,那麼也許。否則,當發生錯誤時,事務將保持打開狀態,直到您明確關閉它或將其回滾爲止。如果發生這種情況,隨着越來越多的事務處於打開狀態(咀嚼資源),您的數據庫將慢慢爬行。不幸的是,我發現有一天公司的開發數據庫自動提交,但他們的生產數據庫卻沒有。我總是發現最好用TRY/CATCH語句來定義BEGIN,ROLLBACK和COMMIT。我用COMMIT更新了代碼。 –

+0

try標籤沒有圍繞在catch上,所以它彈出一個錯誤。我將嘗試放在正確的位置,現在我得到「複雜對象類型不能轉換爲簡單值。」錯誤,類似於我嘗試Select Max(BlogID)。我將繼續關注這一點,因爲我的進展已經停了兩天。 – user3434411