코멘트를 해 주신 분들께 감사드립니다.
이 경우 Generator를 사용하는 게 가장 정확해 보입니다.
처음에는 table 의 field 하나에 generator 가 하나만 있어야 하는 줄 알았습니다 (매뉴얼 어디에도 그런 말이 없는데 왜 그렇게 생각했는지 모르겠지만). 그런데 여러 개 있어도 되는군요. ㅎㅎ.
Dept 가 여러 개이기 때문에 그 숫자만큼 generator 를 만들어 두면 됩니다.
create generator dept_1
create generator dept_2
.......................
등등해서.
그런 다음 새로운 레코드 삽입시 먼저 gen_id() 를 호출하여 그 값을 씁니다.
ibquery1.sql.text := 'select gen_id(dept_1, 1) from rdb$database';
a := ibquery1.fields[0].Asinteger;
ibquery1.sql.text := format('insert into AnyTable (dept) values (%d)', [a]);
ibquery1.execsql;
dept = 2 이면 gen_id (dept_2, 1) 이렇게 써 주면 되구요.
dept 가 많으면 경우에 따라
if dept=1 then ..........gen_id(dept_1,1)
else if dept=2 then ..........gen_id(dept_2,1)
.........................
같이 써야 해서, 불편할 수도 있는데 다행이 sql 문에 들어가는 것이라 불편하지도 않네요.
위 query 문을 다시 쓰면
ibquery1.sql.text := format ('select gen_id(dept_%d, 1) from rdb$database', [dept]);
이렇게 쓰면 dept 값에 따라 query 문의 generator 도 자동적으로 정확하게 지정됩니다.
고수분들이야 다 아시는 내용이겠지만, 혹시라도 같은 고민을 하신 분들은 참조하시라고 작성합니다.
seg 님이 쓰신 글 :
: 안녕하세요
: DB (Interbase) 프로그래밍을 할 때 key 값을 계속 1씩 증가시키는 걸 하려고 합니다.
:
: 전체적인 로직은 다음과 같습니다. SQL문을 사용해 기존의 최대값을 뽑아서 1을 더해 저장하려는 것인데요,
:
:
: with ibq1 do begin
: sql := 'select Max(idvalue) from AnyTable where dept=1';
: Open;
:
: a := Fields[0].Asinteger + 1;
:
: SQL.Text := format('insert into AnyTable (idvalue) values (%d)', [a]);
: ExecSQL;
: end;
:
: 그런데 이런 식으로 할 경우 이 두 SQL 문장이 실행되는 도중에 딴 record 가 입력이 되면, idvalue 가 중복이 되는 사태가 벌어질 수 있을 것 같습니다.
:
: 그래서 Interbase 의 stored procedure 로 작성하면 되는 것인지 알고 싶습니다.
:
:
: select max(idvalue) from anytable where dept=1 into :imax;
: insert into anytable (idvalue) values (:imax+1);
:
: 처럼 말이죠.
:
:
: 그런데 stored procedure 의 경우에도 이 두 개의 SQL 문장 사이에 다시 stored procedure가 호출되면, 같은 idvalue가 생성되거나 할 가능성이 없는지요.
:
: 또 이런 경우 보통 어떻게 해결하는지.. 테이블 전체에 해당되는 것이 아니라, 위에서 보시듯 dept 등 각 조건에 따라 1부터 차례로 값을 주고자 합니다.
|