2. 지원되는 SQL문, 스키마 객체 및 데이터 타입#
이 장은 데이터베이스 링크 사용을 위해 Altibase가 제공하는 SQL 구문과 데이터베이스 링크를 통해서 접근할 수 있는 원격 데이터베이스의 스키마 객체, 그리고 데이터베이스 링크와 함께 사용 가능한 데이터 타입에 대해 설명한다.
데이터베이스 링크와 SQL문#
이 절은 데이터베이스 링크와 함께 사용할 수 있는 SQL구문에 대해 설명한다.
Altibase 데이터베이스 링크는 원격 스키마 객체 접근을 위해 크게 두 종류의 방식을 제공한다. 하나는 이전까지의 버전처럼 위치 표시자(@)를 사용해서 원격 서버의 테이블이나 뷰에 접근하는 방식이고, 다른 하나는 SQL문 전체를 원격 서버로 직접 전송하는 pass-through 방식이다.
Altibase 데이터베이스 링크는 pass-through 방식을 지원하기 위해 REMOTE_TABLE 키워드와 내장된 REMOTE 프로시저와 함수들(이하 REMOTE 함수로 표기)을 제공한다. REMOTE_TABLE 키워드 또는 REMOTE 함수들을 사용하면 SQL문 자체가 원격 서버로 전송되어 원격 서버가 직접 해당 SQL문을 수행한다.
REMOTE 함수들은 SQL문 내의 파라미터 마커에 값을 바인딩할 수 있는 함수와 그렇지 않은 함수로 구분된다.
아래는 SQL 구문 종류 별로 REMOTE_TABLE 키워드와 REMOTE 함수들의 사용 가능 여부를 표로 나타낸 것이다.
REMOTE_TABLE 키워드 | REMOTE_EXECUTE_IMMEDIATE | 바인딩 지원 REMOTE 함수들 | |
---|---|---|---|
DDL 문 | X | O | O |
DCL 문 | X | O | O |
DML 문 (INSERT, UPDATE, DELETE) | X | O | O |
SELECT 문 | O | X | O |
REMOTE_TABLE#
REMOTE_TABLE은 지역 서버에서 입력되는 SELECT구문의 FROM 절에만 사용할 수 있는 키워드이다. REMOTE_TABLE 키워드 뒤에는 원격 서버에서 수행할 SELECT 구문만 지정할 수 있다. 또한, REMOTE_TABLE 키워드는 파라미터 마커가 포함된 SQL문, 즉 바인딩과 함께 사용할 수 없다.
SQL문에 REMOTE_TABLE 키워드를 사용하는 문법은 "4장 데이터베이스 링크 사용법"에서 기술한다.
REMOTE_EXECUTE_IMMEDIATE#
REMOTE_EXECUTE_IMMEDIATE 입력한 SQL문을 데이터베이스 링크를 통해 원격 서버에서 수행하는 내장된 저장 프로시저다. 이 프로시저는 SELECT문을 제외한 Altibase 데이터베이스 링크에서 지원하는 모든 DML문, DDL문과 DCL문을 수행할 수 있다. 또한, 이 프로시저로는 파라미터 마커가 포함된 SQL문의 수행, 즉 바인딩의 사용이 불가능하다.
이 프로시저의 문법은 "4장. 데이터베이스 링크 사용법"을 참고하기 바란다.
바인딩 지원 REMOTE 함수#
데이터베이스 링크를 통해 파라미터 마커가 포함된 SQL문을 실행할 수 있는 REMOTE 함수들에 대해 설명한다.
파라미터 마커가 포함된 SQL문을 실행하고 각 파라미터에 값을 바인딩하기 위해서는 아래의 REMOTE 함수들을 사용하면 된다. 단, 아래의 REMOTE 함수들은 저장 프로시저 내에서만 사용할 수 있고, 호출 순서도 지켜야 한다.
-
REMOTE_ALLOC_STATEMENT
-
REMOTE_BIND_VARIABLE
-
REMOTE_EXECUTE_STATEMENT
-
REMOTE_NEXT_ROW
-
REMOTE_GET_COLUMN_VALUE_type
-
REMOTE_FREE_STATEMENT
아래는 저장 프로시저 내에서 파라미터 마커가 포함된 SELECT 문을 수행하기 위해 REMOTE 함수를 호출하는 순서이다.
-
REMOTE_ALLOC_STATEMENT
-
REMOTE_BIND_VARIABLE
-
REMOTE_EXECUTE_STATEMENT
-
REMOTE_NEXT_ROW
-
REMOTE_GET_COLUMN_VALUE_type
-
REMOTE_FREE_STATEMENT
아래는 저장 프로시저 내에서 SELECT 문 이외의 파라미터 마커가 포함된 DML, DDL 문을 수행하기 위해 REMOTE 함수를 호출하는 순서이다.
-
REMOTE_ALLOC_STATEMENT
-
REMOTE_BIND_VARIABLE
-
REMOTE_EXECUTE_STATEMENT
-
REMOTE_FREE_STATEMENT
각 REMOTE 함수에 대한 문법과 상세한 설명은 "4장 데이터베이스 링크 사용법"을 참고하기 바란다.
접근 가능한 원격 스키마 객체#
이 절에서는 데이터베이스 링크로 접근할 수 있는 원격 스키마 객체들을 설명한다.
[표 2‑1] 데이터베이스 링크로 접근가능한 원격 스키마 객체
원격 스키마 객체 | 위치 표시자 @로 접근 가능한가? | REMOTE 함수로 접근 가능한가? |
---|---|---|
테이블 | O | O |
인덱스 | X | O |
뷰 | O | O |
저장 프로시저 | X | O |
시퀀스 | X | O |
큐 | X | O |
트리거 | X | O |
시노님 | X | O |
제약조건 | X | O |
위의 표에서 보듯이 데이터베이스 링크를 위치 표시자(@)와 함께 사용해서 원격 서버에서 접근할 수 있는 객체는 테이블과 뷰 뿐이다. 그러나, pass-through 방식의 REMOTE 함수를 사용하면 원격 노드의 거의 모든 스키마 객체에 접근이 가능하다.
주의: 위치 표시자(@)는 이전 버전과의 호환성을 위해 지원되며, 위치 표시자(@)를 사용해서는 이전 버전에서와 마찬가지로 원격 서버에서 SELECT 구문만 수행할 수 있다. 또한, 위치 표시자가 포함된 질의는 서버에서 쿼리 최적화가 수행되지 않기 때문에, REMOTE 함수를 사용하는 것이 질의 처리 속도가 더 빠르다.
아래의 절에서는 REMOTE 함수를 사용해서 원격 스키마 객체에 접근하는 방법과 SQL문 예제를 보여준다.
테이블#
데이터베이스 링크의 핵심 기능은 데이터가 서로 다른 데이터베이스에 분산되어 있는 테이블 간의 상호 운용을 제공하는 것이다. Altibase 데이터베이스 링크를 사용해서 원격 테이블에 SELECT, INSERT, UPDATE, DELETE 및 DDL문을 수행할 수 있다.
SELECT 질의의 경우, 아래와 같이 FROM 절에 REMOTE_TABLE 키워드를 사용해서 원격 테이블을 조회할 수 있다.
SELECT * FROM REMOTE_TABLE( link1, 'select * from t1' );
만약 WHERE 절에서 원격 객체를 참조하려면 아래 예제와 같이 부질의를 사용하면 된다.
SELECT * FROM t1 WHERE t1.c1 = ( SELECT * FROM REMOTE_TABLE( link1, 'select c2 from t2' ) );
원격 서버에 DML 또는 DDL문을 수행하려면 아래 예제와 같이 REMOTE_EXECUTE_IMMEDIATE 프로시저를 사용하면 된다.
REMOTE_EXECUTE_IMMEDIATE( 'link1', 'insert into t1 values(1)' );
REMOTE_EXECUTE_IMMEDIATE( 'link1', 'create table t1(c1 integer primary key, c2 integer)' );
파라미터 마커가 포함된 SELECT문의 경우 위의 "바인딩 지원 REMOTE 함수"절에 기술한 순서로 바인딩 지원 REMOTE 함수들을 순서대로 사용하면 되고 DML과 DDL 의 경우도 이와 마찬가지이다.
아래는 파라미터 마커가 포함된 INSERT문을 REMOTE 함수를 사용해서 수행하는 저장 프로시저 예제이다.
DECLARE
statement_id
result
row_count
BEGIN
statement_id := REMOTE_ALLOC_STATEMENT( 'link1', 'insert into T1 values(?)' );
result := REMOTE_BIND_VARIABLE( 'link1', statement_id, 1, '20' );
row_count := REMOTE_EXECUTE_STATEMENT( 'link1', statement_id );
result := REMOTE_FREE_STATEMENT( 'link1', statement_id );
RETURN row_count;
END;
아래는 위치 표시자 '@'를 사용해서 원격 서버의 테이블을 조회하는 예제이다. 위치 표시자 사용 방식은 기존 버전과의 호환성을 유지하기 위해 지원된다.
SELECT * FROM t1@link1;
인덱스#
Altibase 데이터베이스 링크를 사용해서 원격 서버에 인덱스를 생성할 수 있다.
REMOTE_EXECUTE_IMMEDIATE( 'link1', 'create index index1 on t1 (c1 asc, c2 desc)' );
뷰#
뷰에 대해서도 테이블과 마찬가지로 SELECT, DML, DDL문의 수행을 지원하고 사용법도 테이블과 동일하다.
아래는 REMOTE 함수를 사용해서 원격 서버의 뷰를 조회하는 예제이다.
SELECT * FROM REMOTE_TABLE( link1, 'select * from v1' );
아래는 REMOTE 함수를 사용해서 원격 서버에 뷰를 생성하는 예제이다.
REMOTE_EXECUTE_IMMEDIATE( 'link1', 'create view v1 as select c1, c2, c3 from t1' );
아래는 위치 표시자 '@'를 사용해서 원격 서버의 뷰를 조회하는 예제이다.
SELECT * FROM v1@link1;
저장 프로시저#
Altibase 데이터베이스 링크로 원격 서버의 저장 프로시저에 접근할 수 있다. 즉, 지역 서버에서 원격 서버에 저장 프로시저를 생성하고 원격 서버에 존재하는 프로시저를 호출할 수 있다.
지역 서버의 저장 프로시저 내에 REMOTE 함수를 사용할 경우, REMOTE 함수로 접근 가능한 모든 원격 객체를 참조할 수 있다.
아래는 저장 프로시저를 호출하는 SELECT문을 REMOTE_TABLE 키워드를 사용해서 원격 서버에서 수행하는 예제이다.
SELECT * FROM REMOTE_TABLE( link1, 'select remote_function1() from dual' );
SELECT * FROM t1 WHERE t1.c1 = ( SELECT * FROM REMOTE_TABLE( link1, 'select remote_function1() from dual' ) );
아래는 REMOTE_EXECUTE_IMMEDIATE 프로시저를 사용해서, 원격 서버에 저장 프로시저를 생성하고 생성된 프로시저를 호출하는 예제이다.
REMOTE_EXECUTE_IMMEDIATE( 'link1',
'create or replace procedure proc1 as i integer;
begin i := 0;
while i <> 1000
loop
insert into t1 values(i);
i := i + 1;
end loop;
end;
/' );
REMOTE_EXECUTE_IMMEDIATE( 'link1', 'execute proc1' );
제약사항#
지역 서버의 저장 프로시저 내에서 원격 서버의 테이블에 기반한 ROWTYPE 변수 선언과 커서 선언은 할 수 없다.
위치 표시자 '@'를 사용하는 경우 이전 버전과 동일한 제약사항을 가진다. 다시 말해 위치 표시자 '@'를 사용해서 원격 서버에 존재하는 저장 프로시저에 대한 접근은 불가능하나, 지역 서버의 저장 프로시저 내에서 위치 표시자 '@'를 사용해서 원격 서버의 테이블 또는 뷰에 접근하는 것은 가능하다.
시퀀스#
Altibase 데이터베이스 링크로 원격 서버의 시퀀스에 접근할 수 있다.
아래는 시퀀스를 참조하는 SELECT문을 REMOTE_TABLE 키워드를 사용해서 원격 서버에 수행하는 예제이다.
SELECT * FROM REMOTE_TABLE( link1, 'select seq1.currval, seq1.nextval from dual' );
아래는 시퀀스를 참조하는 INSERT문을 REMOTE_EXECUTE_IMMEDIATE 프로시저를 사용해서 원격 서버에 수행하는 예제이다.
REMOTE_EXECUTE_IMMEDIATE( 'link1', 'insert into t1 values(seq1.nextval)' );
아래는 원격 서버에 시퀀스를 생성하는 예제이다.
REMOTE_EXECUTE_IMMEDIATE( 'link1', 'create sequence seq1 start with 1 increment by 1' );
큐#
Altibase 데이터베이스 링크로 원격 서버의 큐에 접근할 수 있다.
아래는 REMOTE_TABLE 키워드를 사용해서 원격 서버의 큐를 조회하는 예제이다.
SELECT * FROM REMOTE_TABLE( link1, 'select message from q1' );
아래는 REMOTE_EXECUTE_IMMEDIATE 프로시저를 사용해서 원격 서버의 큐에 메시지를 입력하는 예제이다.
REMOTE_EXECUTE_IMMEDIATE( 'link1', 'enqueue into q1(message) values(\'test message\')' );
아래는 원격 서버에 큐를 생성하는 예제이다.
REMOTE_EXECUTE_IMMEDIATE( 'link1', 'create queue q1(40) maxrows 1000' );
트리거#
Altibase 데이터베이스 링크로 원격 서버의 트리거에 접근할 수 있다.
아래는 원격 서버에 트리거를 생성하는 예제이다.
REMOTE_EXECUTE_IMMEDIATE( 'link1',
'create trigger trigger1 after delete on orders
referencing old row old_row
for each row as
begin
insert into log1 values( old_row.c1,
old_row.c2,
old_row.c3,
sysdate );
end;
/' );
시노님#
Altibase 데이터베이스 링크로 원격 서버의 시노님에 접근할 수 있다.
아래는 REMOTE_TABLE 키워드를 사용해서 원격 서버의 시노님을 조회하는 예제이다.
SELECT * FROM REMOTE_TABLE( link1, 'select * from synonym_table' );
SELECT * FROM REMOTE_TABLE( link1, 'select synonym_name from user_synonyms' );
아래는 원격 서버의 시노님에 DML 문을 수행하는 예제이다.
REMOTE_EXECUTE_IMMEDIATE( 'link1', 'insert into synonym_table values( seq1.nextval )' );
제약조건#
Altibase 데이터베이스 링크로 원격 서버의 제약조건에 접근할 수 있다.
아래는 원격 서버의 제약조건에 DML 문을 수행하는 예제이다.
REMOTE_EXECUTE_IMMEDIATE( 'link1', 'set constraints all differed' );
아래는 원격 서버의 테이블에 제약조건을 추가하는 DDL 문을 수행하는 예제이다.
REMOTE_EXECUTE_IMMEDIATE( 'link1', 'alter table t1 add constraint const1 unique(c1)' );
DB Link 지원 데이터 타입#
Altibase 데이터베이스 링크는 JDBC 인터페이스를 사용하므로, JDBC v3.0에 명세화된 표준 데이터 타입을 지원한다.
아래 그림은 지역 서버인 Altibase와 AltiLinker 사이의 데이터 타입 변환과 AltiLinker와 각 이기종 데이터베이스의 JDBC 드라이버간의 데이터 타입 변환이 어떻게 이루어지는지를 보여준다.
[그림 2‑1] 데이터 타입 변환
아래의 표는 Altibase 데이터 타입들이 어떤 JDBC 데이터 타입 및 표준 SQL 데이터 타입과 매핑되는지를 보여준다.
[표 2‑2] 데이터베이스 링크 지원 데이터 타입
JDBC 데이터 타입 | Altibase SQL 데이터 타입 | 표준 SQL 데이터 타입 | DB-Link 지원 여부 | 비고 |
---|---|---|---|---|
java.sql.Types.CHAR | CHAR | CHAR | O | |
java.sql.Types.VARCHAR | VARCHAR | VARCHAR | O | |
java.sql.Types.LONGVARCHAR | LONGVARCHAR | X | ||
java.sql.Types.NCHAR | NCHAR | NCHAR | X | JDBC v4.0 |
java.sql.Types.NVARCHAR | NVARCHAR | NVARCHAR | X | JDBC v4.0 |
java.sql.Types.LONGNVARCHAR | LONGNVARCHAR | X | JDBC v4.0 | |
java.sql.Types.NUMERIC | NUMERIC | NUMERIC | O | |
java.sql.Types.DECIMAL | DECIMAL | DECIMAL | O | |
java.sql.Types.BIT | SMALLINT | BIT | O | Altibase의 BIT 타입은 한 비트만 표현 가능한 표준 BIT 타입과 다르므로 SMALLINT 타입으로 맵핑된다. |
BIT (bitset) | X | Altibase의 BIT 타입은 비트 집합을 저장한다. | ||
java.sql.Types.BOOLEAN | SMALLINT | BOOLEAN | O | Altibase는 BOOLEAN 타입을 제공하지 않으므로, SMALLINT 타입으로 맵핑된다. 원격 서버가 Altibase일 경우 이 타입에는 데이터 INSERT가 불가능하다. |
java.sql.Types.TINYINT | SMALLINT | TINYINT | O | Altibase는 TINYINT 타입을 제공하지 않으므로, SMALLINT 타입으로 맵핑된다. |
java.sql.Types.SMALLINT | SMALLINT | SMALLINT | O | |
java.sql.Types.INTEGER | INTEGER | INTEGER | O | |
java.sql.Types.BIGINT | BIGINT | BIGINT | O | |
java.sql.Types.REAL | REAL | REAL | O | |
java.sql.Types.FLOAT | FLOAT | FLOAT | O | |
java.sql.Types.DOUBLE | DOUBLE | DOUBLE | O | |
java.sql.Types.BINARY | BINARY | BINARY | X | 원격 서버가 Altibase일 경우 이 타입에는 데이터 INSERT가 불가능하다. |
java.sql.Types.VARBINARY | VARBINARY | X | ||
java.sql.Types.LONGVARBINARY | LONGVARBINARY | X | ||
java.sql.Types.DATE | DATE | DATE | O | 년도의 값이 0보다 작으면(기원전), Altibase는 0으로 처리한다. |
java.sql.Types.TIME | DATE | TIME | O | Oracle은 TIMESTAMP의 최소 표현 단위가 nano초이나, Altibase는 micro초이므로, nano초가 micro초로 변환된다. |
java.sql.Types.TIMESTAMP | DATE | TIMESTAMP | O | Oracle은 TIMESTAMP의 최소 표현 단위가 nano초이나, Altibase는 micro초이므로, nano초가 micro초로 변환된다. |
또한, 년도의 값이 0보다 작으면(기원전), Altibase는 0으로 처리한다. | ||||
java.sql.Types.CLOB | CLOB | CLOB | X | |
java.sql.Types.NCLOB | NCLOB | X | JDBC v4.0 | |
java.sql.Types.BLOB | BLOB | BLOB | X | |
java.sql.Types.ARRAY | X | |||
java.sql.Types.DISTINCT | X | |||
java.sql.Types.STRUCT | X | |||
java.sql.Types.REF | X | |||
java.sql.Types.DATALINK | X | |||
java.sql.Types.JAVA_OBJECT | X | |||
java.sql.Types.NUMERIC | NUMERIC | NUMERIC | O | |
NIBBLE | X | |||
VARBIT | X | |||
INTERVAL | X |