2011-08-05 10 views
0

我正在使用不具有自動遞增標識列的數據庫(iSeries)。因此,我必須在應用程序中即時生成ID。將ColdFusion應用程序生成的標識值插入到iSeries表中的最佳方式是什麼?

我有實現這個對我來說是用戶定義的函數,因爲我需要生成這些ID數表:

<cffunction name="getNewTableId" returntype="numeric" output="false"> 
    <cfargument name="TableName" type="string" required="true" /> 
    <cfargument name="ColumnName" type="string" required="true" /> 
    <cfargument name="SeedNum" type="numeric" required="false" default="1" /> 

    <cfquery name="qMaxId" datasource="#REQUEST.DSN#"> 
     SELECT  MAX(#ARGUMENTS.ColumnName#) AS Id 
     FROM  #ARGUMENTS.TableName# 
    </cfquery> 

    <cfscript> 
     if (qMaxId.RecordCount && IsValid("integer", qMaxId.Id)) 
      return qMaxId.Id + 1; 

     return ARGUMENTS.SeedNum; 
    </cfscript> 
</cffunction> 

(我知道這是不是很安全,但是這是bare-骨頭只是爲了得到它的工作詮釋他的開發環境現在)

我的問題是,有什麼好處/從INSERT語句中調用該函數,而不是在本地保存的ID值的缺點:

  1. 生成INSERT語句內的ID

    <cfquery datasource="#REQUEST.DSN#"> 
        INSERT INTO MyTable    
         (
          ID, 
          NameTxt 
         ) 
        SELECT #getNewTableId('MyTable','ID')#, 
          <cfqueryparam 
           value="#FORM.MyName#" 
           cfsqltype="CF_SQL_VARCHAR" 
           maxlength="20" /> 
    </cfquery> 
    
  2. 生成ID來INSERT statment之前

    <cfset newId = getNewTableId('MyTable','ID') /> 
    
    <cfquery datasource="#REQUEST.DSN#"> 
        INSERT INTO MyTable    
         (
          ID, 
          NameTxt 
         ) 
        SELECT #newId#, 
          <cfqueryparam 
           value="#FORM.MyName#" 
           cfsqltype="CF_SQL_VARCHAR" 
           maxlength="20" /> 
    </cfquery> 
    

我傾向於傾斜朝第一選擇,因爲ColdFusion的威利準備語句並執行它立即,而不是本地存儲值,然後讓ColdFusion準備SQL語句。

有什麼區別嗎?

+0

我看不出什麼區別。在這兩種情況下,CF首先執行'getNewTableId'。然後處理'INSERT'。但是這兩種選擇都不是線程安 – Leigh

+0

DB2有自動增量。請參閱@JamesA鏈接瞭解更多信息。 – corretge

+0

爲什麼他不能爲您添加標識列,可能值得與DBA交談。在我的環境中,原因是RPG和COBOL程序需要重新編譯,因爲它們依賴於數據庫表的佈局(它們遍歷記錄,它們不使用SQL)。爲了解決這個問題,我建立了另一個模式並在那裏重新創建了表,我可以在那裏修改模式,現在我將它們與觸發器綁定在一起... http:// stackoverflow。com/questions/7017355/db2-keeping-n-columns-in-sync-two-tables – Quaternion

回答

1

AS/400支持在列定義上使用GENERATED ... AS IDENTITY自動遞增標識列。

有關更多詳細信息,請參閱SQL Reference: CREATE TABLE聲明。

+0

不幸的是,我沒有權力在數據庫中分配自動遞增IDENTITY列的能力,所以這沒有幫我。但是,如果您有建議回答我的問題,將不勝感激。 –

+0

對不起,您的原始消息不清楚您指的是數據庫模式而不是數據庫引擎本身。 – jamesallman

0

無論哪種方式,你似乎有重複的可能性。

讓我們說,兩個用戶同時執行相同的操作,並且查詢獲取最大ID需要500毫秒(很長時間,但是爲了舉例),這將不可避免地創建一個重複的ID。兩種解決方案:

  1. 在事務中封裝getID查詢和插入查詢。
  2. 使用某種集羣主鍵(例如id和日期)重做您的表。

至於更好的方式是將id存儲爲變量或者不是,這個問題更好地表達爲:「我會在這個請求的後面的任何一點使用這個id嗎?」

+1

請注意,默認事務級別不會阻止其他線程。所以它需要一個'serializable'事務。 http://www.garyrgilbert.com/blog/index.cfm/2008/7/15/Cftransaction-Explained(儘管如果@JamesA是正確的,並且自動遞增的列確實在本地支持,那將是最好的選擇。 ) – Leigh

+0

確實,如果操作員有能力修改模式,我不確定何時應答。 –

+0

是的,我也不確定。我只是說*如果*他有他的druthers,去與本機選項;) – Leigh

相關問題