OS 환경 : Oracle Linux 8.4 (64bit)
DB 환경 : Oracle Database 23.7.0.25.01 ai for Oracle Cloud and Engineered Systems, Free
방법 : 오라클 23ai 신기능 Select AI 사용 테스트(non-adb)
오라클 23.7 버전부터 adb가 아닌 일반 온프레미스db에도 dbms_cloud 패키지를 설치할 수 있음
(2025년 04월 기준 아직까지 23.7 일반 버전은 나오지 않았지만 Oracle Cloud and Engineered Systems 버전과 Free 버전으로 테스트함)
아래 글 작성시에는 free 버전 설치시 23.4버전이 설치되었지만 지금은 23.7 버전으로 설치됨
참고 : Oracle Linux 8.4에 Oracle 23ai Free RPM 설치 및 삭제 가이드 ( https://positivemh.tistory.com/1095 )
하지만 dbms_cloud가 23.7에 기본적으로 탑재되어있지 않고 수동으로 설치를 해주어야함
이전 게시글에서 23.7 버전에 dbms_cloud를 설치하는 방법을 설명했음
이 게시글은 dbms_cloud가 설치된 상태에서 진행함
참고 : 오라클 23ai 신기능 dbms_cloud 설치(non-adb) ( https://positivemh.tistory.com/1203 )
본문에서는 Select AI 기능을 설명하고 dbms_cloud 패키지중 하나인 dbms_cloud_ai를 이용해 Select AI를 테스트해봄
Select AI 란?
Select AI는 23ai의 신기능으로 출시 초기에는 Oracle Cloud Infrastructure(OCI)상의 Oracle Autonomous Database(ADB)에서만 구동 가능했지만
23.7버전부터 non-adb에서도 실행이 가능함
Select AI는 자연어를 사용하여 데이터베이스에 쿼리할 수 있는 기능임
대규모 언어 모델(LLM)을 활용하여 사용자의 자연어 입력을 Oracle SQL로 변환함
Select AI는 자연어 프롬프트를 처리하고, 데이터베이스의 메타데이터로 이를 보완한 후, SQL 쿼리를 생성하고 실행함
이를 통해 사용자는 SQL 문법을 몰라도 자연어로 데이터베이스와 상호작용하여 원하는 정보를 얻을 수 있음
Select AI는 벡터 임베딩 생성부터 벡터 저장소를 활용한 의미적 유사성 검색을 통해 사용자의 프롬프트에 기반한 관련 콘텐츠 검색까지 검색 증강 생성(RAG) 프로세스를 자동화함
그 외에도 합성 데이터 생성, 대화 내역 지원 등의 기능이 있으며, 모두 SQL 인터페이스를 통해 제공됨
Select AI에서 지원하는 AI 공급업체
공급업체 | 지원 LLM 예시 | 주요 용도 |
OCI Generative AI | meta.llama-3.1-70b-instruct (default) meta.llama-3.1-405b-instruct meta.llama-3.2-90b-vision-instruct etc.. |
runsql, showsql, explainsql, narrate, chat 등 모든 Select AI 작업 |
Azure OpenAI | GPT-4o GPT-4 GPT-4 Turbo with Vision etc.. |
자연어 프롬프트, chat 작업 및 Select AI RAG에서 SQL을 생성하는 데 가장 적합 |
OpenAI | gpt-3.5-turbo (default) gpt-4o gpt-4o-mini etc.. |
자연어 프롬프트, chat 작업 및 Select AI RAG에서 SQL을 생성하는 데 가장 적합 |
Cohere | command (default) command-nightly (experimental) command-r etc.. |
chat 작업에 가장 적합 |
gemini-1.5-flash (default) gemini-1.5-pro gemini-1.0-pro etc.. |
자연어 프롬프트, chat 작업 및 Select AI RAG에서 SQL을 생성하는 데 가장 적합 | |
Anthropic | claude-3-5-sonnet-20240620 (default) claude-3-opus-20240229 claude-3-sonnet-20240229 etc.. |
자연어 프롬프트, chat 작업 및 Select AI RAG에서 SQL을 생성하는 데 가장 적합 |
Hugging Face | Mixtral-8x7B-Instruct-v0.1 (default) Meta-Llama-3-70B-Instruct Qwen1.5-1.8B etc.. |
자연어 프롬프트, chat 작업 및 Select AI RAG에서 SQL을 생성하는 데 가장 적합 |
참고 : https://docs.oracle.com/en-us/iaas/autonomous-database-serverless/doc/select-ai-about.html
Select AI에서 사용가능한 명령어
runsql : 자연어 프롬프트에 대해 SQL 문을 생성하고 해당 SQL 쿼리를 실행하여 결과를 출력함(기본값)
narrate : 데이터베이스에서 실행된 SQL 쿼리 결과를 LLM에 전달하여 그 결과를 자연어로 설명함
*참고로 벡터 인덱스가 AI 프로파일에 지정되어 RAG가 활성화된 경우, 시스템은 지정된 트랜스포머 모델을 사용해 프롬프트로부터 벡터 임베딩을 생성하고, 벡터 저장소에 대해 의미 기반 유사도 검색을 수행함.
이후 벡터 저장소에서 검색된 콘텐츠를 사용자 프롬프트에 추가하고, 이를 LLM에 전달하여 해당 정보를 기반으로 응답을 생성함
showsql : 자연어 프롬프트에 대해 생성된 SQL 문만 표시함
explainsql : 생성된 SQL 문을 자연어로 설명함. 이 옵션은 생성된 SQL을 AI 제공자에게 보내고, AI가 이를 자연어 설명으로 변환하여 제공함
chat : 사용자 프롬프트를 그대로 LLM에 전달하여 응답을 생성함. 이 응답은 사용자에게 그대로 반환됨
테스트
api키 발급
먼저 openai에서 api키를 받아와야함
https://openai.com/index/openai-api/
사이트 접속 후 key 발급
발급 받은 키 저장(이 창을 닫으면 더이상 키를 볼수없으니 개인 공간에 저장해둬야함)
발급된 키 확인
23ai_selectai 용으로 발급받은 내 키는 아래와 같은 형태로 만들어져있음
sk-pr**-*****wA
api 키 발급 및 토큰도 구매해야함
나의경우 토큰이 없는 경우 제대로 동작하지 않아 10$만 충전해서 사용함
참고 : https://mixedcode.com/blog/detail?pid=6
LLM용 ACL 생성
*유저이름은 IMSI이고 OPENAI api를 사용함
*pdb에서 sys 유저로 수행
1
2
3
4
5
6
7
8
9
10
11
12
|
SQL>
BEGIN
DBMS_NETWORK_ACL_ADMIN.APPEND_HOST_ACE(
host => 'api.openai.com',
ace => xs$ace_type(privilege_list => xs$name_list('http'),
principal_name => 'IMSI',
principal_type => xs_acl.ptype_db)
);
END;
/
PL/SQL procedure successfully completed.
|
imsi 유저에 DBMS_CLOUD_AI 권한 부여
1
2
3
|
SQL> grant execute on dbms_cloud_ai to imsi;
Grant succeeded.
|
LLM용 자격증명 생성
*위에서 openai에서 발급 받은 api 키를 넣어줘야함
*pdb에서 sys 유저로 수행하라고 되어있었지만 에러발생해서 imsi 유저에서 생성함
1
2
3
4
5
6
7
8
9
|
SQL>
begin
dbms_cloud.create_credential (
credential_name => 'OPENAI_CRED',
username => 'IMSI',
password => 'sk-pr*******wA' --api key 삽입
);
end;
/
|
참고. pdb의 sys유저에서 실행시 에러 발생함
1
2
3
4
5
6
|
*
ERROR at line 1:
ORA-06598: insufficient INHERIT PRIVILEGES privilege
ORA-06512: at "C##CLOUD$SERVICE.DBMS_CLOUD", line 1
ORA-06512: at line 2
Help: https://docs.oracle.com/error-help/db/ora-06598/
|
참고. credential 삭제 방법
1
2
3
4
5
6
|
SQL>
begin
dbms_cloud.drop_credential (
credential_name => 'OPENAI_CRED');
end;
/
|
imsi 유저에 emp, dept 테이블 생성
1
2
3
|
SQL> @emp.sql
SQL> select * from emp;
SQL> select * from dept;
|
참고 : 오라클 EMP, DEPT table 생성 스크립트 ( https://positivemh.tistory.com/99 )
Select AI 프로필 생성
*pdb에서 sys 유저로 수행하라고 되어있었지만 에러발생해서 imsi 유저에서 생성함
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
SQL>
BEGIN
DBMS_CLOUD_AI.create_profile(
profile_name => 'TEST_OPENAI',
attributes => '{"provider": "openai",
"comments": "true",
"model": "gpt-4o-mini",
"temperature": 0.2,
"max_tokens": 4096,
"conversation": "true",
"credential_name": "OPENAI_CRED",
"object_list": [{"owner": "IMSI", "name": "EMP"},
{"owner": "IMSI", "name": "DEPT"}]}');
END;
/
PL/SQL procedure successfully completed.
|
옵션 설명 :
comments : Select AI가 LLM에 테이블 주석을 전송하여 SQL을 작성하는데 도움을 줄지 여부를 결정함
conversation : 프로필에 대화 기록이 활성화되어 있는지 여부를 나타냄
credential_name : LLM 제공자를 인증하는데 사용되는 자격 증명 이름임
object_list : 소유자와 SQL로 자연어 번역이 가능한 객체 이름을 지정하는 JSON 객체 배열임(스키마의 모든 테이블을 넣으려면 owner 만 넣으면됨)
model : 저렴한 gpt-4o-mini 모델을 사용함
참고. pdb의 sys유저에서 실행시 에러 발생함
1
2
3
4
5
6
|
*
ERROR at line 1:
ORA-06598: insufficient INHERIT PRIVILEGES privilege
ORA-06512: at "C##CLOUD$SERVICE.DBMS_CLOUD_AI", line 1
ORA-06512: at line 2
Help: https://docs.oracle.com/error-help/db/ora-06598/
|
참고. profile 삭제
1
2
3
|
SQL> exec dbms_cloud_ai.drop_profile(profile_name => 'TEST_OPENAI');
PL/SQL procedure successfully completed.
|
생성된 profile 확인(sys, system 유저 또는 dba권한 가진 유저로 실행)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
SQL>
set lines 200 pages 1000
col profile_name for a20
col owner for a20
col description for a30
col created for a20
col last_modified for a20
select profile_id, profile_name, owner, description
, to_char(created, 'yyyy/mm/dd hh24:mi:ss') created, to_char(last_modified, 'yyyy/mm/dd hh24:mi:ss') last_modified
from dba_cloud_ai_profiles;
PROFILE_ID PROFILE_NAME OWNER DESCRIPTION CREATED LAST_MODIFIED
---------- -------------------- -------------------- ------------------------------ -------------------- --------------------
2 TEST_OPENAI IMSI 2025/04/02 23:24:51 2025/04/02 23:24:51
|
정상적으로 생성됨
생성된 profile 속성 확인(sys, system 유저 또는 dba권한 가진 유저로 실행)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
SQL>
set lines 200 pages 1000
col profile_name for a20
col owner for a20
col attribute_name for a20
col attribute_value for a70
select profile_id, profile_name, owner, attribute_name, attribute_value
, to_char(last_modified, 'yyyy/mm/dd hh24:mi:ss') last_modified
from dba_cloud_ai_profile_attributes
order by 2,3,4;
PROFILE_ID PROFILE_NAME OWNER ATTRIBUTE_NAME ATTRIBUTE_VALUE LAST_MODIFIED
---------- -------------------- -------------------- -------------------- ---------------------------------------------------------------------- --------------------
2 TEST_OPENAI IMSI comments true 2025/04/02 23:24:51
2 TEST_OPENAI IMSI conversation true 2025/04/02 23:24:51
2 TEST_OPENAI IMSI credential_name OPENAI_CRED 2025/04/02 23:24:51
2 TEST_OPENAI IMSI max_tokens 4096 2025/04/02 23:24:51
2 TEST_OPENAI IMSI model gpt-4o-mini 2025/04/02 23:24:51
2 TEST_OPENAI IMSI object_list [{"owner":"IMSI","name":"EMP"},{"owner":"IMSI","name":"DEPT"}] 2025/04/02 23:24:51
2 TEST_OPENAI IMSI provider openai 2025/04/02 23:24:51
2 TEST_OPENAI IMSI temperature 0.2 2025/04/02 23:24:51
8 rows selected.
|
정상적으로 생성됨
현재 세션에서 AI 프로필을 설정(imsi 유저로 실행)
1
2
3
4
|
SQL> conn imsi/imsi@localhost:1521/oracle23pdb1
SQL> exec dbms_cloud_ai.set_profile (profile_name => 'TEST_OPENAI');
PL/SQL procedure successfully completed.
|
이제 Select AI를 사용할수 있음
Select AI에서 사용가능한 명령어
runsql : 자연어 프롬프트에 대해 SQL 문을 생성하고 해당 SQL 쿼리를 실행하여 결과를 출력함(기본값)
narrate : 데이터베이스에서 실행된 SQL 쿼리 결과를 LLM에 전달하여 그 결과를 자연어로 설명함
*참고로 벡터 인덱스가 AI 프로파일에 지정되어 RAG가 활성화된 경우, 시스템은 지정된 트랜스포머 모델을 사용해 프롬프트로부터 벡터 임베딩을 생성하고, 벡터 저장소에 대해 의미 기반 유사도 검색을 수행함.
이후 벡터 저장소에서 검색된 콘텐츠를 사용자 프롬프트에 추가하고, 이를 LLM에 전달하여 해당 정보를 기반으로 응답을 생성함
showsql : 자연어 프롬프트에 대해 생성된 SQL 문만 표시함
explainsql : 생성된 SQL 문을 자연어로 설명함. 이 옵션은 생성된 SQL을 AI 제공자에게 보내고, AI가 이를 자연어 설명으로 변환하여 제공함
chat : 사용자 프롬프트를 그대로 LLM에 전달하여 응답을 생성함. 이 응답은 사용자에게 그대로 반환됨
*참고로 select ai 실행시 에러가 발생한다면 LLM용 자격증명 생성 부분에서 api 키를 올바르게 넣었는지 확인해봐야함
1
2
3
4
5
6
7
8
|
SQL> select ai chat 'what is the oci?';
select ai chat 'what is the oci?'
*
ERROR at line 1:
ORA-20401: Authorization failed for URI - bearer://api.openai.com/v1/chat/completions
ORA-06512: at "C##CLOUD$SERVICE.DBMS_CLOUD", line 2060
ORA-06512: at "C##CLOUD$SERVICE.DBMS_CLOUD_AI", line 10137
ORA-06512: at line 1
|
*그리고 set_profile 명령을 수행하지 않고 select ai 쿼리를 수행하면 from 절을 입력하라고 표시됨
1
2
3
4
5
6
|
SQL> select ai runsql 'Who has the highest salary?';
select ai runsql 'Who has the highest salary?'
*
ERROR at line 1:
ORA-00923: FROM keyword not found where expected
Help: https://docs.oracle.com/error-help/db/ora-00923/
|
가장 높은 연봉을 가진 사람을 조회해봄
Who has the highest salary? 라는 질문으로 각 기능을 테스트해봄
Select AI runsql 기능 테스트
1
2
3
4
5
6
7
8
9
|
SQL>
set timing on
select ai runsql 'Who has the highest salary?';
Employee_N Salary
---------- ----------
KING 5000
Elapsed: 00:00:02.49
|
정상적으로 조회됨, 약 2.5초 소요됨
특정 테이블에서만 질문하려면 from 절을 넣어줘도 되는듯함
1
2
3
4
5
|
SQL> select ai runsql 'Who has the highest salary?' from emp;
Employee_N Salary
---------- ----------
KING 5000
|
Select AI narrate 기능 테스트
1
2
3
4
5
6
7
|
SQL> select ai narrate 'Who has the highest salary?';
RESPONSE
-------------------------------------------------------------
The employee with the highest salary is KING, who earns 5000.
Elapsed: 00:00:02.05
|
쿼리에 대한 결과를 자연어로 잘 설명해줌
Select AI showsql 기능 테스트
1
2
3
4
5
6
7
8
9
|
SQL> select ai showsql 'Who has the highest salary?';
RESPONSE
---------------------------------------------------------------------
SELECT "E"."ENAME" AS "Employee_Name", "E"."SAL" AS "Salary"
FROM "IMSI"."EMP" "E"
WHERE "E"."SAL" = (SELECT MAX("E1"."SAL") FROM "IMSI"."EMP" "E1")
Elapsed: 00:00:02.05
|
쿼리가 잘 표시됨
Select AI explainsql 기능 테스트
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
|
SQL> select ai explainsql 'Who has the highest salary?';
RESPONSE
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Here is the SQL query to find the employee with the highest salary, using table aliases and easy-to-read column names, while considering case sensitivity:
```sql
SELECT "E"."ENAME" AS "Employee_Name", "E"."SAL" AS "Salary"
FROM "IMSI"."EMP" "E"
WHERE "E"."SAL" = (SELECT MAX("E1"."SAL") FROM "IMSI"."EMP" "E1");
```
### Explanation:
1. **SELECT Clause**:
- `"E"."ENAME" AS "Employee_Name"`: This selects the employee's name from the `EMP` table and renames the column to "Employee_Name" for better readability.
- `"E"."SAL" AS "Salary"`: This selects the salary of the employee and renames the column to "Salary".
2. **FROM Clause**:
- `"IMSI"."EMP" "E"`: This specifies the table from which to retrieve the data. The table `EMP` is in the schema `IMSI`. The alias `"E"` is used for easier reference to this table in the query.
3. **WHERE Clause**:
- The condition checks for the maximum salary:
- `(SELECT MAX("E1"."SAL") FROM "IMSI"."EMP" "E1")`: This subquery retrieves the highest salary from the same `EMP` table. The alias `"E1"` is used for this subquery to differentiate it from the
outer query.
### Summary:
This query effectively retrieves the name and salary of the employee with the highest salary from the `EMP` table in the `IMSI` schema, ensuring that all identifiers are case-sensitive and properly en
closed in double quotes.
Elapsed: 00:00:07.90
번역
RESPONSE
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
다음은 대소문자를 구분하면서 테이블 별칭과 읽기 쉬운 열 이름을 사용하여 가장 높은 급여를 받는 직원을 찾는 SQL 쿼리입니다.
```sql
SELECT "E"."ENAME" AS "Employee_Name", "E"."SAL" AS "Salary"
FROM "IMSI"."EMP" "E"
WHERE "E"."SAL" = (SELECT MAX("E1"."SAL") FROM "IMSI"."EMP" "E1");
```
### 설명:
1. **SELECT 절**:
- `"E"."ENAME" AS "Employee_Name"`: `EMP` 테이블에서 직원 이름을 선택하고 가독성을 높이기 위해 열 이름을 "Employee_Name"으로 변경합니다.
- `"E"."SAL" AS "Salary"`: 직원의 급여를 선택하고 열 이름을 "Salary"로 변경합니다.
2. **FROM 절**:
- `"IMSI"."EMP" "E"`: 데이터를 검색할 테이블을 지정합니다. 테이블 `EMP`는 스키마 `IMSI`에 있습니다. 쿼리에서 이 테이블을 쉽게 참조할 수 있도록 별칭 `"E"`를 사용합니다.
3. **WHERE 절**:
- 이 조건은 최대 급여를 확인합니다.
- `(SELECT MAX("E1"."SAL") FROM "IMSI"."EMP" "E1")`: 이 하위 쿼리는 동일한 `EMP` 테이블에서 가장 높은 급여를 검색합니다. 이 하위 쿼리를 외부 쿼리와 구분하기 위해 별칭 `"E1"`을 사용합니다.
### 요약:
이 쿼리는 `IMSI` 스키마의 `EMP` 테이블에서 가장 높은 급여를 받는 직원의 이름과 급여를 효과적으로 검색합니다. 이때 모든 식별자는 대소문자를 구분하고 큰따옴표로 올바르게 묶어야 합니다.
|
쿼리와 함께 쿼리에 대한 마크업 형식(``, **등)으로 설명을 잘 해줌
Select AI chat 기능 테스트
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
SQL> select ai chat 'what is the oci?';
RESPONSE
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
OCI can refer to several different things depending on the context. Here are a few common meanings:
1. **Oracle Cloud Infrastructure (OCI)**: A cloud computing service offered by Oracle Corporation that provides a range of cloud services including computing, storage, networking, and database managem
ent.
2. **Open Container Initiative (OCI)**: An organization that aims to create open standards for container formats and runtimes, ensuring compatibility and interoperability among different container tec
hnologies.
3. **Overseas Citizenship of India (OCI)**: A form of permanent residency available to people of Indian origin and their spouses, allowing them to live and work in India indefinitely.
If you have a specific context in mind, please provide more details so I can give you a more precise answer!
번역
RESPONSE
-------------------------------------------------------------------------------------------------------------------------------------------
OCI는 맥락에 따라 여러 가지 다른 의미를 가질 수 있습니다. 다음은 몇 가지 일반적인 의미입니다.
1. **Oracle Cloud Infrastructure(OCI)**: Oracle Corporation에서 제공하는 클라우드 컴퓨팅 서비스로, 컴퓨팅, 스토리지, 네트워킹, 데이터베이스 관리를 포함한 다양한 클라우드 서비스를 제공합니다.
2. **Open Container Initiative(OCI)**: 컨테이너 형식 및 런타임에 대한 개방형 표준을 개발하여 다양한 컨테이너 기술 간의 호환성과 상호 운용성을 보장하는 것을 목표로 하는 조직입니다.
3. **Overseas Citizenship of India(OCI)**: 인도계와 그 배우자에게 제공되는 영주권으로, 인도에서 무기한 거주 및 근무가 가능합니다.
특정 맥락을 염두에 두고 계신다면 더 자세한 정보를 제공해 주시면 더 정확한 답변을 드릴 수 있습니다!
|
정상적으로 일반 질문에 대한 답변이 출력됨
일반적으로 chatgpt에서 질문하듯이 사용가능한 기능임
참고1. autotrace 결과 확인
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
SQL> set timing on
SQL> set autot on
SQL> exec dbms_cloud_ai.set_profile (profile_name => 'TEST_OPENAI');
PL/SQL procedure successfully completed.
SQL> select ai runsql 'Who has the highest salary?';
Employee_N Salary
---------- ----------
KING 5000
Elapsed: 00:00:02.49
Execution Plan
----------------------------------------------------------
ERROR:
ORA-00923: FROM keyword not found where expected
Help: https://docs.oracle.com/error-help/db/ora-00923/
SP2-0612: Error generating AUTOTRACE EXPLAIN report
Help: https://docs.oracle.com/error-help/db/sp2-0612/
Statistics
----------------------------------------------------------
986 recursive calls
32 db block gets
847 consistent gets
0 physical reads
728 redo size
690 bytes sent via SQL*Net to client
108 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
1 sorts (memory)
0 sorts (disk)
1 rows processed
|
autotrace는 from 절이 없어서 플랜이 나오지 않고 에러 발생함, 하지만 stat은 나옴
참고용2. xplan 결과 확인
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
|
SQL> alter session set statistics_level = all;
Session altered.
SQL> exec dbms_cloud_ai.set_profile (profile_name => 'TEST_OPENAI');
PL/SQL procedure successfully completed.
SQL> select ai runsql 'Please show me the name, department, and annual salary of the lowest paid person.';
Name Department Annual Salary
---------- -------------- -------------
SMITH RESEARCH 9600
SQL> SELECT * FROM DBMS_XPLAN.DISPLAY_CURSOR(NULL, NULL, 'ADVANCED ALLSTATS LAST');
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
SQL_ID 06749jpcc6kzm, child number 0
-------------------------------------
SELECT "E"."ENAME" AS "Name", "D"."DNAME" AS "Department",
("E"."SAL" * 12) AS "Annual Salary" FROM "IMSI"."EMP" "E" JOIN
"IMSI"."DEPT" "D" ON "E"."DEPTNO" = "D"."DEPTNO" WHERE "E"."SAL" =
(SELECT MIN("SAL") FROM "IMSI"."EMP")
Plan hash value: 4175708089
----------------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows |E-Bytes| Cost (%CPU)| E-Time | A-Rows | A-Time | Buffers |
----------------------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | | 7 (100)| | 1 |00:00:00.01 | 16 |
| 1 | NESTED LOOPS | | 1 | 1 | 55 | 4 (0)| 00:00:01 | 1 |00:00:00.01 | 16 |
| 2 | NESTED LOOPS | | 1 | 1 | 55 | 4 (0)| 00:00:01 | 1 |00:00:00.01 | 15 |
|* 3 | TABLE ACCESS FULL | EMP | 1 | 1 | 33 | 3 (0)| 00:00:01 | 1 |00:00:00.01 | 14 |
| 4 | SORT AGGREGATE | | 1 | 1 | 13 | | | 1 |00:00:00.01 | 7 |
| 5 | TABLE ACCESS FULL | EMP | 1 | 14 | 182 | 3 (0)| 00:00:01 | 14 |00:00:00.01 | 7 |
|* 6 | INDEX UNIQUE SCAN | PK_DEPT | 1 | 1 | | 0 (0)| | 1 |00:00:00.01 | 1 |
| 7 | TABLE ACCESS BY INDEX ROWID| DEPT | 1 | 1 | 22 | 1 (0)| 00:00:01 | 1 |00:00:00.01 | 1 |
----------------------------------------------------------------------------------------------------------------------------------
Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------
3 - SEL$58A6D7F6 / "E"@"SEL$1"
4 - SEL$3
5 - SEL$3 / "EMP"@"SEL$3"
6 - SEL$58A6D7F6 / "D"@"SEL$1"
7 - SEL$58A6D7F6 / "D"@"SEL$1"
Outline Data
-------------
/*+
BEGIN_OUTLINE_DATA
IGNORE_OPTIM_EMBEDDED_HINTS
OPTIMIZER_FEATURES_ENABLE('23.1.0')
DB_VERSION('23.1.0')
ALL_ROWS
OUTLINE_LEAF(@"SEL$3")
OUTLINE_LEAF(@"SEL$58A6D7F6")
MERGE(@"SEL$1" >"SEL$2")
OUTLINE(@"SEL$2")
OUTLINE(@"SEL$1")
FULL(@"SEL$58A6D7F6" "E"@"SEL$1")
INDEX(@"SEL$58A6D7F6" "D"@"SEL$1" ("DEPT"."DEPTNO"))
LEADING(@"SEL$58A6D7F6" "E"@"SEL$1" "D"@"SEL$1")
USE_NL(@"SEL$58A6D7F6" "D"@"SEL$1")
NLJ_BATCHING(@"SEL$58A6D7F6" "D"@"SEL$1")
PUSH_SUBQ(@"SEL$3")
FULL(@"SEL$3" "EMP"@"SEL$3")
END_OUTLINE_DATA
*/
Predicate Information (identified by operation id):
---------------------------------------------------
3 - filter("E"."SAL"=)
6 - access("E"."DEPTNO"="D"."DEPTNO")
Column Projection Information (identified by operation id):
-----------------------------------------------------------
1 - "E"."ENAME"[VARCHAR2,10], "E"."SAL"[NUMBER,22], "E"."DEPTNO"[NUMBER,22], "D"."DNAME"[VARCHAR2,14]
2 - "E"."ENAME"[VARCHAR2,10], "E"."SAL"[NUMBER,22], "E"."DEPTNO"[NUMBER,22], "D".ROWID[ROWID,10]
3 - "E"."ENAME"[VARCHAR2,10], "E"."SAL"[NUMBER,22], "E"."DEPTNO"[NUMBER,22]
4 - (#keys=0) MIN("SAL")[22]
5 - (rowset=256) "SAL"[NUMBER,22]
6 - "D".ROWID[ROWID,10]
7 - "D"."DNAME"[VARCHAR2,14]
Note
-----
- dynamic statistics used: dynamic sampling (level=2)
- this is an adaptive plan
Query Block Registry:
---------------------
SEL$1 (PARSER)
SEL$2 (PARSER)
SEL$58A6D7F6 (VIEW MERGE SEL$2 ; SEL$1) [FINAL]
SEL$3 (PARSER) [FINAL]
86 rows selected.
|
xplan 결과는 제대로 표시되지만 "select ai ~" 쿼리에 대한 실행계획이 아닌 select ai로 생성된 "SELECT "E"."ENAME" AS~" 쿼리에 대한 실행계획이 표시됨
참고용3. 한글 입력시 결과 이상
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
SQL> select ai runsql '가장 낮은 급여를 받는 사람의 이름과 부서, 연봉을 알려주세요.';
Employee Number Employee N Job Title Manager Number Hire Date Salary Commission Department Number Department Nam Location
--------------- ---------- --------- -------------- --------- ---------- ---------- ----------------- -------------- -------------
7839 KING PRESIDENT 17-NOV-81 5000 10 ACCOUNTING NEW YORK
7698 BLAKE MANAGER 7839 01-MAY-81 2850 30 SALES CHICAGO
7782 CLARK MANAGER 7839 09-JUN-81 2450 10 ACCOUNTING NEW YORK
7566 JONES MANAGER 7839 02-APR-81 2975 20 RESEARCH DALLAS
7788 SCOTT ANALYST 7566 13-JUL-87 3000 20 RESEARCH DALLAS
7902 FORD ANALYST 7566 03-DEC-81 3000 20 RESEARCH DALLAS
7369 SMITH CLERK 7902 17-DEC-80 800 20 RESEARCH DALLAS
7499 ALLEN SALESMAN 7698 20-FEB-81 1600 300 30 SALES CHICAGO
7521 WARD SALESMAN 7698 22-FEB-81 1250 500 30 SALES CHICAGO
7654 MARTIN SALESMAN 7698 28-SEP-81 1250 1400 30 SALES CHICAGO
7844 TURNER SALESMAN 7698 08-SEP-81 1500 0 30 SALES CHICAGO
7876 ADAMS CLERK 7788 13-JUL-87 1100 20 RESEARCH DALLAS
7900 JAMES CLERK 7698 03-DEC-81 950 30 SALES CHICAGO
7934 MILLER CLERK 7782 23-JAN-82 1300 10 ACCOUNTING NEW YORK
14 rows selected.
|
한글로 질문했을때는 번역의 문제인지 전체 결과가 나와버림
영어로 질문시 정확하게 나옴
1
2
3
4
5
|
SQL> select ai runsql 'Please show me the name, department, and annual salary of the lowest paid person.';
Name Department Annual Salary
---------- -------------- -------------
SMITH RESEARCH 9600
|
*SMITH의 salay가 800인데 *12(연봉)으로 계산해서 결과로 보여줌
참고4. v$sql에 select ai 구문 있는지 확인
1
2
3
4
5
6
7
8
9
10
11
|
SQL> select sql_id, sql_text from v$sql where sql_text like '%select ai%';
SQL_ID SQL_TEXT
------------- ------------------------------------------------------------------
43rk68t8js1ry select sql_id, sql_text from v$sql where sql_text like '%select ai%'
SQL> select sql_id, sql_text from v$sql where sql_text like '%runsql%'
SQL_ID SQL_TEXT
------------- ------------------------------------------------------------------
7nsb95zqacjfm select sql_id, sql_text from v$sql where sql_text like '%runsql%'
|
select ai 쿼리는 v$sql에 나오지 않음
참고5. select ai 에 이미 실행한 쿼리를 다시 수행하면 결과가 바로 출력됨
어딘가에 결과를 저장하고 있는듯함
저장소? 캐시?가 어디인지는 정확히 찾지못했음
결론 :
23.7버전부터 일반 DB(non-ADB)에서도 DBMS_CLOUD 및 Select AI 사용 가능함
DBMS_CLOUD_AI 패키지를 통한 LLM 연동 시 OpenAI, Azure, OCI 등 다양한 공급자를 지원함
runsql, narrate, showsql 명령은 약 2.5초 소요됨
explainsql 명령은 결과 내용이 길어서 그런지 약 8초 소요됨
chat 명령은 일반적으로 gpt에 질문하는 기능인데 굳이 sqlplus에서 실행을 자주하진 않을것 같음
잘쓰면 아주 유용하게 사용가능할듯함
현재로썬 외부(opanai 등)에 접속을 해서 llm 결과를 가져오는거라
실제 업무에서 사용하기는 힘들지 않을까 싶음. 외부 네트워크를 사용하지 않고 로컬 llm을 이용할수 있다면 더 유용하게 사용가능할듯함
참조 :
2748362.1
https://docs.oracle.com/en/database/oracle/oracle-database/23/sutil/dbms_cloud-family-packages.html
https://docs.oracle.com/en/database/oracle/oracle-database/23/nfcoa/ru_23_7.html#GUID-104803-1
https://bryangrenn.blogspot.com/2025/03/23.7-Selectai.html?m=1
https://oracle-cloud.tistory.com/entry/Select-AI-%EC%BF%BC%EB%A6%AC-%EC%83%9D%EC%84%B1-%EA%B8%B0%EB%8A%A5-%EC%86%8C%EA%B0%9C
https://blog.cloudnueva.com/select-ai-is-not-a-toy
https://docs.oracle.com/en-us/iaas/autonomous-database-serverless/doc/select-ai-concepts.html
https://docs.oracle.com/en-us/iaas/autonomous-database-serverless/doc/select-ai-examples.html
https://docs.oracle.com/en-us/iaas/autonomous-database-serverless/doc/sql-generation-ai-autonomous.html
https://docs.oracle.com/en/cloud/paas/autonomous-database/dedicated/hsarg/index.html#articletitle
'ORACLE > Admin' 카테고리의 다른 글
오라클 19c templates 경로의 seeddata 데이터베이스 (2) | 2025.04.20 |
---|---|
오라클 19c dbca silent 시 템플릿별 컴포넌트 비활성화 설정 (0) | 2025.04.14 |
오라클 23ai 신기능 dbms_cloud 설치(non-adb) (0) | 2025.04.13 |
오라클 19c 유저별 테이블스페이스 quota 확인 및 변경 (0) | 2025.04.07 |
오라클 19c 파티션 인덱스의 테이블스페이스 변경 (0) | 2025.03.31 |