2011-08-05 2 views
0

자동 증분 ID 열이없는 데이터베이스 (iSeries)로 작업하고 있습니다. 따라서 응용 프로그램에서 ID를 생성해야합니다. 나는 여러 테이블을 위해 이러한 ID를 생성해야하기 때문에ColdFusion 응용 프로그램 생성 ID 값을 iSeries 테이블에 삽입하는 가장 좋은 방법은 무엇입니까?

나는 나를 위해이 작업을 수행하는 사용자 정의 함수가 있습니다

<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> 

(난이 매우 안전하지 알고 있지만,이 베어입니다 뼈는 지금 그가 개발 환경하는 int 작업하세요)

내 질문은, 무엇 혜택/로컬 ID 값을 저장 반대로, INSERT 문 내에서 함수를 호출의 단점 :.

  1. <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 전에 한 Statment를 INSERT하기 위해 생성 삽입 한 Statment 내부 ID를 생성

    <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

IDA가 왜 당신을 위해 추가 할 수 없는지에 대해 DBA와 이야기하는 것이 가치가 있습니다. 제 환경에서 RPG 및 COBOL 프로그램은 DB 테이블의 레이아웃에 의존하기 때문에 다시 컴파일해야합니다 (레코드를 반복하고 SQL을 사용하지 않기 때문에). 이 문제를 극복하기 위해 다른 스키마를 설정하고 거기에서 테이블을 다시 만들었습니다. 스키마를 변경할 수 있습니다. 이제 트리거와 함께 연결합니다 ... http : // stackoverflow.com/questions/7017355/db2-keeping-n-columns-in-two-tables – Quaternion

답변

1

AS/400은 열 정의에서 GENERATED ... AS IDENTITY을 사용하여 자동 증가 ID 열을 지원합니다.

자세한 내용은 SQL Reference: CREATE TABLE 문을 참조하십시오.

+0

글쎄, 유감스럽게도, 자동 증가 IDENTITY 컬럼을 데이터베이스에 할당 할 수있는 능력이 없다. 도와주세요. 그러나 제 질문에 대한 답변을 주시면 감사하겠습니다. –

+0

죄송합니다. 원본 메시지가 데이터베이스 엔진 자체가 아니라 데이터베이스 스키마를 언급하고 있다는 것이 명확하지 않았습니다. – jamesallman

0

어느 쪽이든 복제의 가능성이있는 것으로 보입니다.

두 명의 사용자가 동시에 동일한 작업을 수행하고 최대 ID를 얻기위한 쿼리가 500ms (오랜 시간이지만 예를 들면 목적)가 걸리면 필연적으로 중복 ID가 생성됩니다. 두 가지 솔루션 :

  1. 트랜잭션에서 getID 쿼리와 insert 쿼리를 모두 캡슐화합니다.
  2. ID와 날짜와 같은 일종의 클러스터 된 기본 키를 사용하여 테이블을 다시 실행하십시오.

변수로 ID를 저장하는 것이 더 나은지 여부는 더 나은 질문입니다. "나중에이 ID를이 요청에 사용하겠습니까?"

+1

기본 트랜잭션 수준은 다른 스레드를 차단하지 않습니다. 따라서 '직렬화 가능'트랜잭션이 필요합니다. http://www.garyrgilbert.com/blog/index.cfm/2008/7/15/Cftransaction-Explained (@JamesA가 정확하고 자동 증가 열이 실제로 기본적으로 지원되는 경우에도 최상의 선택이 될 수 있습니다.) – Leigh

+0

사실, op가 스키마를 수정할 수있는 능력이 있다면 대답 할 때 확신이 들지 않았습니다. –

+0

예, 확실하지 않았습니다. 나는 방금 druthers를 가지고 있다면 * native * 옵션으로 가겠다는 것을 의미했다.) – Leigh

관련 문제