Skip to content

Commit 0c0c7c8

Browse files
Merge pull request #520 from ALTIBASE/BUG-50684
INC-48302 lob select 주의 사항
2 parents 765de3a + 3c94dfa commit 0c0c7c8

File tree

6 files changed

+139
-81
lines changed

6 files changed

+139
-81
lines changed

Manuals/Altibase_7.1/kor/CLI User's Manual.md

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6890,13 +6890,18 @@ SQLTransact(SQL_NULL_HENV, dbc, SQL_COMMIT);
68906890

68916891
### LOB 데이터 처리 방식
68926892

6893-
#### LOB 위치 입력기(LOB Locator)
6893+
Altibase는 CLI에서 LOB데이터를 처리하기위해 LOB 위치 입력기(LOB Locator)를 이용한다. LOB Locator는 LOB 데이터에 대응되는 고유값으로 Altibase 서버의 내부 자료구조이다. LOB 데이터를 연산하기 위해서는 먼저 LOB Locator를 획득해야 하며, 이를 통해 LOB 데이터를 읽거나 쓸 수 있다. LOB Locator는 MVCC와 관련하여 특정 시점의 LOB 데이터를 가리키기 때문에 LOB Locator를 발생시킨 트랜잭션과 생명주기를 같이하며, 그 트랜잭션에 종속된다.
68946894

6895-
CLI의 일부 함수에서 LOB 데이터를 처리할 때 LOB 위치 입력기를 사용하기 때문에 LOB 위치 입력기를 이용한 LOB 데이터 처리 방식에 대한 이해가 필요하다.
6895+
#### 자동 커밋 모드 해제
6896+
6897+
LOB 위치 입력기는 트랜잭션에 종속적이기 때문에 **CLI에서 LOB 위치 입력기를 이용하여 LOB 데이터를 처리하려면 반드시 자동 커밋 모드를 해제해야 한다.**
68966898

6897-
LOB 위치 입력기는 LOB 데이터를 가리키는 Altibase 서버의 내부 자료구조이며 트랜잭션에 종속된다.
6899+
자동 커밋 모드를 해제하면 LOB 위치 입력기를 얻어오는 CLI 함수와 LOB 데이터를 읽고 쓰는 CLI 함수는 하나의 트랜잭션내에서 개별 작업으로 동작되어 LOB 위치 입력기를 공유할 수 있다. 반면, 자동 커밋 모드에서는 개별 트랜잭션으로 동작하기 때문에 두 트랜잭션 간에 LOB 위치 입력기를 공유할 수 없다.
6900+
6901+
> **LOB 위치 입력기를 이용한 트랜잭션 커밋 시 주의사항**
68986902

6899-
CLI에서 LOB 데이터를 처리하는 과정은 LOB 위치 입력기를 얻는 작업과 LOB 위치 입력기를 이용하여 LOB 데이터를 읽고 쓰는 작업으로 나뉜다.
6903+
1. 자동 커밋 해제 모드에서 LOB 데이터를 읽고 쓰는 CLI 함수 수행 중 예상치 못한 에러가 발생하면, 내부적으로 초기화된 데이터가 남아 있을 수 있어 **반드시 트랜잭션을 롤백해야 한다.**
6904+
2. NOT NULL 제약이 있는 LOB 타입 컬럼에 NULL 값을 INSERT 혹은 UPDATE 수행하면 [Unable to insert (or update) NULL into NOT NULL column.] 에러가 발생한다. 이 경우 초기화된 데이터가 남아 있어 **반드시 트랜잭션을 롤백해야 한다.**
69006905

69016906
#### LOB 위치 입력기 얻기
69026907

@@ -6918,24 +6923,22 @@ LOB 위치 입력기를 얻은 후에 이것을 이용하여 LOB 데이터를
69186923
- SQLPutLob
69196924
- SQLTrimLob
69206925

6921-
#### 자동 커밋 모드 해제
6922-
6923-
LOB 위치 입력기는 트랜잭션에 종속적이기 때문에 **CLI에서 LOB 위치 입력기를 이용하여 LOB 데이터를 처리하려면 반드시 자동 커밋 모드를 해제해야 한다.**
6926+
#### LOB 데이터의 조회(SELECT)
69246927

6925-
자동 커밋 모드에서 LOB 위치 입력기를 얻어오는 CLI 함수와 LOB 데이터를 읽고 쓰는 CLI 함수는 각각 하나의 트랜잭션이기 때문에 두 트랜잭션 간에 LOB 위치 입력기를 공유할 수 없다. 반면, 자동 커밋 모드를 해제하면 LOB 위치 입력기를 얻어오는 CLI 함수와 LOB 데이터를 읽고 쓰는 CLI 함수는 하나의 트랜잭션에서 개별 작업이 되며 LOB 위치 입력기를 공유할 수 있다. 따라서 개별 작업의 성공 여부에 따라 트랜잭션을 커밋할 때 SQL 수행 결과가 달라질 수 있음을 주의해야 한다.
6928+
LOB 데이터를 SELECT 할때, 내부적으로는 LOB Locator를 얻어와서 처리되기 때문에 연관된 트랜잭션이 열린 상태가 된다. 따라서 사용자는 명시적으로 commit 또는 rollback과 같은 트랜잭션 종료 작업을 추가로 해주어야 한다.
69266929

6927-
> **LOB 위치 입력기를 이용한 트랜잭션 커밋 시 주의사항**
6930+
> [!CAUTION]
6931+
>
6932+
> 만약, 사용자가 명시적으로 commit 또는 rollback 과 같은 트랜잭션 종료 작업을 하지 않으면, 데이터베이스의 메모리 사용량이 증가할 수 있다.
69286933

6929-
이 예시는 LOB 칼럼을 가진 테이블에 INSERT, UPDATE 문을 수행할 때 해당한다.
6934+
#### 자원 해제하기
69306935

6931-
아래 표의 `결과 1`에서 커밋을 수행하면, LOB 타입 칼럼이 있는 레코드는 LOB 타입 칼럼이 널 값으로 반영될 수 있다. LOB 타입 칼럼의 값이 널 상태로 남기지 않으려면 **반드시 트랜잭션을 롤백해야 한다.**
6936+
LOB 데이터와 관련한 작업이 완료된 경우, 관련된 자원을 해제해주어야 한다. 관련 CLI 함수는 아래와 같다.
69326937

6933-
LOB 타입 칼럼에 NOT NULL 제약조건이 정의되어 있다면 `결과 2` 상황이 발생할 수 있으며, 이때는 에러가 발생하고 부분 롤백 되므로 CLI에서 LOB 데이터 처리를 할 수 없다.
6938+
* [SQLFreeLob](#sqlfreelob)
6939+
* [SQLEndTran](#sqlendtran)
69346940

6935-
| 개별 작업 순서 | 개별 작업 | CLI 함수 | 결과 1 | 결과 2 |
6936-
| :------------: | :---------------------------------- | :---------------------------- | :----: | :----: |
6937-
| 1 | LOB 위치 입력기를 얻어오는 CLI 함수 | SQLBindParameter / SQLExecute | 성공 | 실패 |
6938-
| 2 | LOB 데이터를 읽고 쓰는 CLI 함수 | SQLPutLob | 실패 | - |
6941+
SQLFreeLob 함수는 Lob Locator와 관련된 자원을 해제할 뿐, 트랜잭션을 종료하지는 않는다.
69396942

69406943
### LOB 데이터 타입
69416944

Manuals/Altibase_7.1/kor/JDBC User's Manual.md

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2972,11 +2972,14 @@ while(sRs.next())
29722972

29732973
##### BLOB 데이터 읽기
29742974

2975+
LOB 데이터를 읽을 때, 내부적으로는 Lob Locator를 이용하기 때문에 반드시 commit 또는 rollback과 같은 명시적인 트랜잭션 종료 작업을 추가해야 한다.
2976+
29752977
###### 1. InputStream 객체와 getBinaryStream 메소드를 사용한 방법
29762978

2977-
```
2979+
```java
29782980
...
2979-
PreparedStatement sPstmt = connection().prepareStatement("SELECT BLOB_COLUMN
2981+
sCon = getConnection();
2982+
PreparedStatement sPstmt = sCon.prepareStatement("SELECT BLOB_COLUMN
29802983
FROM BLOB_TABLE");
29812984
ResultSet sRs = sPstmt.executeQuery();
29822985
while(sRs.next())
@@ -2986,15 +2989,17 @@ while(sRs.next())
29862989
...
29872990
}
29882991
...
2992+
sCon.commit();
29892993
```
29902994

29912995

29922996

29932997
###### 2. getBlob 메소드와 InputStream 객체를 사용한 방법
29942998

2995-
```
2999+
```java
29963000
...
2997-
PreparedStatement sPstmt = connection().prepareStatement("SELECT BLOB_COLUMN
3001+
sCon = getConnection();
3002+
PreparedStatement sPstmt = sCon.prepareStatement("SELECT BLOB_COLUMN
29983003
FROM BLOB_TABLE");
29993004
ResultSet sRs = sPstmt.executeQuery();
30003005
while(sRs.next())
@@ -3005,17 +3010,19 @@ while(sRs.next())
30053010
...
30063011
}
30073012
...
3013+
sCon.commit();
30083014
```
30093015

30103016

30113017

30123018
###### 3. getBlob 메소드와 byte 배열을 사용한 방법
30133019

3014-
```
3020+
```java
30153021
...
30163022
final int sReadLength = 100;
30173023

3018-
PreparedStatement sPstmt = connection().prepareStatement("SELECT BLOB_COLUMN FROM BLOB_TABLE");
3024+
sCon = getConnection();
3025+
PreparedStatement sPstmt = sCon.prepareStatement("SELECT BLOB_COLUMN FROM BLOB_TABLE");
30193026

30203027
ResultSet sRs = sPstmt.executeQuery();
30213028

@@ -3034,8 +3041,8 @@ while(sRs.next())
30343041
}
30353042
...
30363043
}
3037-
30383044
...
3045+
sCon.commit();
30393046
```
30403047

30413048

Manuals/Altibase_7.3/kor/CLI User's Manual.md

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6900,13 +6900,18 @@ SQLTransact(SQL_NULL_HENV, dbc, SQL_COMMIT);
69006900

69016901
### LOB 데이터 처리 방식
69026902

6903-
#### LOB 위치 입력기(LOB Locator)
6903+
Altibase는 CLI에서 LOB데이터를 처리하기위해 LOB 위치 입력기(LOB Locator)를 이용한다. LOB Locator는 LOB 데이터에 대응되는 고유값으로 Altibase 서버의 내부 자료구조이다. LOB 데이터를 연산하기 위해서는 먼저 LOB Locator를 획득해야 하며, 이를 통해 LOB 데이터를 읽거나 쓸 수 있다. LOB Locator는 MVCC와 관련하여 특정 시점의 LOB 데이터를 가리키기 때문에, LOB Locator를 발생시킨 트랜잭션과 생명주기를 같이하며, 그 트랜잭션에 종속된다.
69046904

6905-
CLI의 일부 함수에서 LOB 데이터를 처리할 때 LOB 위치 입력기를 사용하기 때문에 LOB 위치 입력기를 이용한 LOB 데이터 처리 방식에 대한 이해가 필요하다.
6905+
#### 자동 커밋 모드 해제
6906+
6907+
LOB 위치 입력기는 트랜잭션에 종속적이기 때문에 **CLI에서 LOB 위치 입력기를 이용하여 LOB 데이터를 처리하려면 반드시 자동 커밋 모드를 해제해야 한다.**
69066908

6907-
LOB 위치 입력기는 LOB 데이터를 가리키는 Altibase 서버의 내부 자료구조이며 트랜잭션에 종속된다.
6909+
자동 커밋 모드를 해제하면 LOB 위치 입력기를 얻어오는 CLI 함수와 LOB 데이터를 읽고 쓰는 CLI 함수는 하나의 트랜잭션내에서 개별 작업으로 동작되어 LOB 위치 입력기를 공유할 수 있다. 반면, 자동 커밋 모드에서는 각각의 개별 트랜잭션으로 동작하기 때문에 두 트랜잭션 간에 LOB 위치 입력기를 공유할 수 없다.
69086910

6909-
CLI에서 LOB 데이터를 처리하는 과정은 LOB 위치 입력기를 얻는 작업과 LOB 위치 입력기를 이용하여 LOB 데이터를 읽고 쓰는 작업으로 나뉜다.
6911+
> **LOB 위치 입력기를 이용한 트랜잭션 커밋 시 주의사항**
6912+
6913+
1. 자동 커밋 해제 모드에서 LOB 데이터를 읽고 쓰는 CLI 함수 수행 중 예상치 못한 에러가 발생하면, 내부적으로 초기화된 데이터가 남아 있을 수 있어 **반드시 트랜잭션을 롤백해야 한다.**
6914+
2. NOT NULL 제약이 있는 LOB 타입 컬럼에 NULL 값을 INSERT 혹은 UPDATE 수행하면 [Unable to insert (or update) NULL into NOT NULL column.] 에러가 발생한다. 이 경우 초기화된 데이터가 남아 있어 **반드시 트랜잭션을 롤백해야 한다.**
69106915

69116916
#### LOB 위치 입력기 얻기
69126917

@@ -6928,16 +6933,22 @@ LOB 위치 입력기를 얻은 후에 이것을 이용하여 LOB 데이터를
69286933
- SQLPutLob
69296934
- SQLTrimLob
69306935

6931-
#### 자동 커밋 모드 해제
6936+
#### LOB 데이터의 조회(SELECT)
69326937

6933-
LOB 위치 입력기는 트랜잭션에 종속적이기 때문에 **CLI에서 LOB 위치 입력기를 이용하여 LOB 데이터를 처리하려면 반드시 자동 커밋 모드를 해제해야 한다.**
6938+
LOB 데이터를 SELECT 할때, 내부적으로는 LOB Locator를 얻어와서 처리되기 때문에 연관된 트랜잭션이 열린 상태가 된다. 따라서 사용자는 명시적으로 commit 또는 rollback과 같은 트랜잭션 종료 작업을 추가로 해주어야 한다.
69346939

6935-
자동 커밋 모드를 해제하면 LOB 위치 입력기를 얻어오는 CLI 함수와 LOB 데이터를 읽고 쓰는 CLI 함수는 하나의 트랜잭션에서 개별 작업이 되어 LOB 위치 입력기를 공유할 수 있다. 반면, 자동 커밋 모드에서는 각각의 개별 트랜잭션으로 동작하기 때문에 두 트랜잭션 간에 LOB 위치 입력기를 공유할 수 없다.
6940+
> [!CAUTION]
6941+
>
6942+
> 만약, 사용자가 명시적으로 commit 또는 rollback 과 같은 트랜잭션 종료 작업을 하지 않으면, 데이터베이스의 메모리 사용량이 증가할 수 있다.
69366943

6937-
> **LOB 위치 입력기를 이용한 트랜잭션 커밋 시 주의사항**
6944+
#### 자원 해제하기
69386945

6939-
1. 자동 커밋 해제 모드에서 LOB 데이터를 읽고 쓰는 CLI 함수 수행 중 예상치 못한 에러가 발생하면, 내부적으로 초기화된 데이타가 남아 있을 수 있어 **반드시 트랜잭션을 롤백해야 한다.**
6940-
2. NOT NULL 제약이 있는 LOB 타입 컬럼에 NULL 값을 INSERT 혹은 UPDATE 수행하면 [Unable to insert (or update) NULL into NOT NULL column.] 에러가 발생한다. 이 경우 초기화된 데이터가 남아 있어 **반드시 트랜잭션을 롤백해야 한다.**
6946+
LOB 데이터와 관련한 작업이 완료된 경우, 관련된 자원을 해제해주어야 한다. 관련 CLI 함수는 아래와 같다.
6947+
6948+
* [SQLFreeLob](#sqlfreelob)
6949+
* [SQLEndTran](#sqlendtran)
6950+
6951+
SQLFreeLob 함수는 Lob Locator와 관련된 자원을 해제할 뿐, 트랜잭션을 종료하지는 않는다.
69416952

69426953
### LOB 데이터 타입
69436954

Manuals/Altibase_7.3/kor/JDBC User's Manual.md

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2908,11 +2908,14 @@ while(sRs.next())
29082908

29092909
##### BLOB 데이터 읽기
29102910

2911+
LOB 데이터를 읽을 때, 내부적으로는 Lob Locator를 이용하기 때문에 반드시 commit 또는 rollback과 같은 명시적인 트랜잭션 종료 작업을 추가해야 한다.
2912+
29112913
###### 1. InputStream 객체와 getBinaryStream 메소드를 사용한 방법
29122914

2913-
```
2915+
```java
29142916
...
2915-
PreparedStatement sPstmt = connection().prepareStatement("SELECT BLOB_COLUMN
2917+
sCon = getConnection();
2918+
PreparedStatement sPstmt = sCon.prepareStatement("SELECT BLOB_COLUMN
29162919
FROM BLOB_TABLE");
29172920
ResultSet sRs = sPstmt.executeQuery();
29182921
while(sRs.next())
@@ -2922,15 +2925,17 @@ while(sRs.next())
29222925
...
29232926
}
29242927
...
2928+
sCon.commit();
29252929
```
29262930

29272931

29282932

29292933
###### 2. getBlob 메소드와 InputStream 객체를 사용한 방법
29302934

2931-
```
2935+
```java
29322936
...
2933-
PreparedStatement sPstmt = connection().prepareStatement("SELECT BLOB_COLUMN
2937+
sCon = getConnection();
2938+
PreparedStatement sPstmt = sCon.prepareStatement("SELECT BLOB_COLUMN
29342939
FROM BLOB_TABLE");
29352940
ResultSet sRs = sPstmt.executeQuery();
29362941
while(sRs.next())
@@ -2941,17 +2946,19 @@ while(sRs.next())
29412946
...
29422947
}
29432948
...
2949+
sCon.commit();
29442950
```
29452951

29462952

29472953

29482954
###### 3. getBlob 메소드와 byte 배열을 사용한 방법
29492955

2950-
```
2956+
```java
29512957
...
29522958
final int sReadLength = 100;
29532959

2954-
PreparedStatement sPstmt = connection().prepareStatement("SELECT BLOB_COLUMN FROM BLOB_TABLE");
2960+
sCon = getConnection();
2961+
PreparedStatement sPstmt = sCon.prepareStatement("SELECT BLOB_COLUMN FROM BLOB_TABLE");
29552962

29562963
ResultSet sRs = sPstmt.executeQuery();
29572964

@@ -2970,8 +2977,8 @@ while(sRs.next())
29702977
}
29712978
...
29722979
}
2973-
29742980
...
2981+
sCon.commit();
29752982
```
29762983

29772984

@@ -3250,11 +3257,14 @@ while(sRs.next())
32503257

32513258
##### CLOB 데이터 읽기
32523259

3260+
LOB 데이터를 읽을 때, 내부적으로는 Lob Locator를 이용하기 때문에 반드시 commit 또는 rollback과 같은 명시적인 트랜잭션 종료 작업을 추가해야 한다.
3261+
32533262
###### 1. Reader 객체와 getCharacterStream 메소드를 사용한 방법
32543263

3255-
```
3264+
```java
32563265
...
3257-
PreparedStatement sPstmt = connection().prepareStatement("SELECT CLOB_COLUMN FROM CLOB_TABLE");
3266+
sCon = getConnection();
3267+
PreparedStatement sPstmt = sCon.prepareStatement("SELECT CLOB_COLUMN FROM CLOB_TABLE");
32583268

32593269
ResultSet sRs = sPstmt.executeQuery();
32603270

@@ -3265,15 +3275,17 @@ while(sRs.next())
32653275
...
32663276
}
32673277
...
3278+
sCon.commit();
32683279
```
32693280

32703281

32713282

32723283
###### 2. Reader 객체 와 getClob 메소드를 사용한 방법
32733284

3274-
```
3285+
```java
32753286
...
3276-
PreparedStatement sPstmt = connection().prepareStatement("SELECT CLOB_COLUMN FROM CLOB_TABLE");
3287+
sCon = getConnection();
3288+
PreparedStatement sPstmt = sCon.prepareStatement("SELECT CLOB_COLUMN FROM CLOB_TABLE");
32773289

32783290
ResultSet sRs = sPstmt.executeQuery();
32793291

@@ -3285,17 +3297,19 @@ while(sRs.next())
32853297
...
32863298
}
32873299
...
3300+
sCon.commit();
32883301
```
32893302

32903303

32913304

32923305
###### 3. getClob 메소드와 String 객체를 사용한 방법
32933306

3294-
```
3307+
```java
32953308
...
32963309
final int sReadLength = 100;
32973310

3298-
PreparedStatement sPstmt = connection().prepareStatement("SELECT CLOB_COLUMN FROM CLOB_TABLE");
3311+
sCon = getConnection();
3312+
PreparedStatement sPstmt = sCon.prepareStatement("SELECT CLOB_COLUMN FROM CLOB_TABLE");
32993313

33003314
ResultSet sRs = sPstmt.executeQuery();
33013315

@@ -3314,8 +3328,8 @@ while(sRs.next())
33143328
}
33153329
...
33163330
}
3317-
33183331
...
3332+
sCon.commit();
33193333
```
33203334

33213335

0 commit comments

Comments
 (0)