모범 사례 및 튜토리얼

오라클 PL/SQL에서 카우치베이스 자바스크립트 UDF로 쉽게 전환할 수 있는 도구

PL/SQL이란 무엇인가요?

PL/SQL은 구문 내에서 SQL 문을 수용하도록 특별히 설계된 절차적 언어입니다. 조건 및 루프와 같은 절차적 언어 요소를 포함하며 예외(런타임 오류)를 처리할 수 있습니다.

PL/SQL은 오라클 데이터베이스에 기본으로 제공되며, IBM DB2, PostgreSQL, MySQL 등의 데이터베이스는 호환성 기능을 통해 PL/SQL 구성을 지원합니다.

자바스크립트 UDF란 무엇인가요?

JavaScript UDF는 PL/SQL을 대체하는 Couchbase의 대안입니다.

JavaScript UDF는 JavaScript의 범용 스크립팅 유연성을 데이터베이스에 도입하여 최신 데이터베이스 시스템에서 동적이고 강력한 작업을 수행할 수 있게 하고 데이터 쿼리, 처리 및 변환의 유연성을 향상시킵니다.

Couchbase, 몽고DB, 스노우플레이크, 구글 빅쿼리 등 대부분의 최신 데이터베이스는 자바스크립트 UDF를 지원합니다.

문제

오라클에서 카우치베이스로 마이그레이션하는 사용자들이 흔히 겪는 문제는 PL/SQL 스크립트를 포팅하는 것입니다. PL/SQL을 지원하는 대신 Couchbase에서는 사용자가 JavaScript로 사용자 정의 함수를 구성할 수 있습니다(2021년부터 지원됨).

JavaScript UDF를 사용하면 변형 및 JSON 데이터를 쉽고 직관적으로 조작할 수 있습니다. UDF로 전달된 변형 객체는 네이티브 JavaScript 유형과 값으로 변환됩니다.

이로 인한 의도치 않은 결과는 지난 10년 동안 존재해 온 대부분의 RDBMS가 개발자에게 절차적 구조, SQL과의 통합, 오류 처리, 함수 및 프로시저, 트리거, 커서를 지원하는 SQL에 대한 절차적 확장(PL/pgSQL, PL/SQL) 또는 최소한 함수 및 프로시저(Sakila 같은)를 사용하여 데이터베이스에 액세스하도록 강력히 권장해 왔다는 점입니다. 이러한 방식에서 벗어나려면 모든 스크립트를 다시 작성해야 합니다.

특히 2000년대 작성되어 그 이후로 유지 관리되고 있는 PL/SQL 스크립트를 다룰 때 코드를 다시 작성하는 것은 지루한 작업인 경우가 많습니다. 이러한 스크립트는 복잡하고 수천 줄에 이르는 경우가 많기 때문에 일반 기업 사용자에게는 부담스러울 수 있습니다.

솔루션

이상적인 접근 방식은 완전히 새로운 PL/SQL 평가기를 개발하는 것이지만, 그렇게 하려면 과도한 엔지니어링 시간이 필요하고 동일한 사용 사례에 대해 이미 현대적이고 안정적이며 빠른 JSEvaluator가 있는데 왜 다른 평가기를 지원해야 할까요?

따라서 이 문제는 AI와 LLM의 지속적인 발전을 활용하기에 완벽한 사용 사례입니다. 이것이 바로 우리가 여기서 한 일입니다. 유니티는 제너레이티브 AI 모델을 사용하여 PL/SQL을 JSUDF로 변환하는 작업 자동화.

2024년 6월 기준, 모델에는 제한된 컨텍스트 창이 있습니다., w즉, PL/SQL이 오류에 더 오래 걸리게 됩니다:  

이는 GPT4용이라는 점에 유의하세요.

그렇다면 AI가 더 강력해지고 더 많은 토큰을 허용할 때까지 기다려야 할까요(무어의 법칙처럼 AI의 컨텍스트 길이 대 정밀도)?

아니요, 여기는 ANTLR, a 파서 생성기 도구가 들어옵니다. ANTLR은 컴파일러와 인터프리터 개발에 사용되는 것으로 잘 알려져 있습니다. 이렇게 하면 큰 스크립트를 독립적으로 번역할 수 있는 작은 단위로 나눌 수 있습니다.

그렇다면 이제 우리는 트랜스파일러? 글쎄요, 맞기도 하고 아니기도 합니다.

트랜스파일러의 스테이지:

    1. 어휘 분석(토큰화)
    2. 구문 분석(구문 분석)
    3. 시맨틱 분석
    4. 중간 표현(IR) 생성
    5. 최적화(선택 사항)
    6. 타겟 코드 생성

AI 번역기의 작동 방식

위의 1,2단계는 ANTLR을 사용하여 수행됩니다. ANTLR의 리스너 인터페이스를 사용하여 다음을 수행합니다. 개별 프로시저/함수/익명 블록을 가져옵니다.와 같이 독립적인 코드 블록으로 변환합니다. 프로시저/함수/익명 블록 자체가 컨텍스트 창을 초과하는 경우에는 문 수준에서 번역합니다(여기에는 정의되지 않았지만 이전 어딘가에 변수/함수 호출의 사용이 존재한다고 LLM이 가정하는 경우).

그 후 3, 4, 5, 6단계, 즉 각 PL/SQL 블록을 블록의 작동 의미를 보존하고 구문적으로 정확한 JavaScript 함수로 최대한 변환하는 작업은 LLM(예: GPT)에 맡깁니다.

결과는 놀랍게도 매우 긍정적이었습니다. 번역 정확도는 80-85%입니다.

이 솔루션의 또 다른 장점은 한 번에 한 가지 작업에 집중함으로써 잡념을 줄여 보다 정확한 번역을 할 수 있다는 점입니다.

시각화하려면:

automate the conversion of PL/SQL to JSUDF

도구 사용 방법

실행 파일은 다음과 같은 명령줄 인수를 기대합니다:

-u: 카펠라 로그인 이메일
-p: 카펠라 로그인 비밀번호
-cpaddr: 채팅-완성 API용 카펠라 URL
-orgid: 채팅 완료 API 경로의 조직 ID
-cbhost: 노드-ip: cbcluster 노드
-cbuser: 클러스터-사용자 이름: 데이터베이스 액세스를 통해 추가된 cbcluster 사용자
-cbpassword: 클러스터-암호: 데이터베이스 액세스를 통해 추가된 cb클러스터 암호
-cbport: 쿼리 서비스 tls 포트: 보통 18093
파일 경로 , 즉 번역해야 하는 PL/SQL 스크립트의 경로입니다.
출력-> 출력 디렉터리에서 이름이 같은 파일이 plsql 파일은 번역된 자바스크립트 라이브러리 코드로 생성됩니다.

예시입니다:

cat example1.sql

위의 스크립트를 간단히 설명합니다:

    • 외부 루프는 x를 1000씩 증가시키고 카운터를 1씩 증가시키면서 4회 반복 실행됩니다.
    • 내부 루프는 x를 1씩 증가시키고 카운터를 1씩 증가시키면서 4회 반복 실행됩니다.

테스트 PL/SQL에서 번역기를 실행합니다:

JSUDF를 출력합니다:

cat output/example1.js

번역된 스크립트에는 다음과 같은 함수가 있습니다. nestedloop (LLM에 의해 생성된 이름)은 원래 익명 PL/SQL 블록이 지정한 대로 정확하게 수행합니다.

참고: 명명된 함수/프로시저의 경우 번역된 JS 함수는 동일한 이름을 갖습니다. 익명 블록의 경우 LLM은 자체적으로 생성한 이름을 사용합니다.

알려진 문제

PL/SQL과 JS는 서로 다른 두 가지 언어이며, Oracle과 Couchbase에서 지원되는 방식은 두 언어 간에 깔끔한 직접 매핑을 허용하지 않습니다. 

다음은 저희가 발견한 몇 가지 제한 사항과 이를 해결하기 위해 구현한 해결 방법입니다:

콘솔 로그가 지원되지 않습니다.

dbms_output.put 기본 제공 프로시저 및 기타 2개의 유사한 기본 제공 프로시저가 있습니다, dbms_output.put_line 그리고 dbms_output.new_line 은 다음과 같이 번역됩니다. console.log()를 사용할 수 있지만 console.log는 브라우저 API이며 Couchbase의 JavaScript 평가 구현에서는 지원되지 않습니다. Couchbase 이벤트 함수가 다음을 지원한다는 점을 고려할 때 이 문제는 자주 요청되어 왔습니다. print() 문에는 있지만 자바스크립트 UDF에는 없습니다.

해결 방법:

사용자는 로깅 버킷.

로그는 다음에 삽입하는 문서의 일부로 삽입됩니다. 기본값.기본값 컬렉션에 추가합니다. 문서는 다음과 같이 보일 것입니다:

사용자는 로깅을 선택하여 자신의 로그를 조회할 수 있습니다:

예시입니다:

오리지널 PL/SQL

JavaScript UDF로 번역됨

이는 이미 도구에 구현되어 있습니다.


로그를 보려면 다음과 같이 하세요:

2. 교차 패키지 함수 호출

패키지 사양에 나열된 프로시저/함수는 전역이며, 다른 패키지에서 다음을 통해 사용할 수 있습니다. "패키지_이름"."공개_프로시저/함수". 그러나 가져오기-내보내기 구문은 CouchBase의 JavaScript 평가 구현에서 지원되지 않으므로 CouchBase의 JavaScript 라이브러리에서도 마찬가지입니다.

해결 방법:

라이브러리 간 함수 호출의 경우 "lib_name"."function"()를 사용하면 사용자는 참조된 라이브러리가 있어야 합니다. "lib_name" 이미 생성된 경우 다음을 통해 확인할 수 있습니다. GET /evaluator/v1/libraries

참조된 함수 "function" 또한 글로벌 UDF로 생성될 것으로 예상되며, 이는 GET /admin/functions_cache를 통해 확인하거나 system:functions 키스페이스를 선택하여 확인할 수 있습니다. 이렇게 하면 SQL++/N1QL을 통해 함수에 액세스할 수 있습니다.

예시입니다:

수학_유틸 패키지

show_sum 패키지

번역된 코드:

프로그램에 의해 자동으로 처리되며, 사람의 눈으로 확인해야 한다는 경고가 표시됩니다!

3. 글로벌 변수

PL/SQL은 패키지 수준 및 세션 수준 전역 변수를 지원하지만, 메모리 누수가 우려되는 전역 변수는 JSUDF에서 의도적으로 지원되지 않습니다.

제안된 해결 방법을 사용하려면 생성된 번역을 수동으로 조정해야 합니다. 예를 들어


전역 변수를 수정하는 모든 함수는 이를 인수로 받아 호출자에게 반환해야 합니다.

increment_counter:

전역만 읽는 모든 함수는 이를 인수로 받아들일 수 있습니다.

show_global:

라이브러리로 패키지 보내기

이 섹션에서는 도구를 사용하여 엔드투엔드 패키지에서 라이브러리로 변환하는 방법을 보여 줍니다.

샘플 PL/SQL 패키지:

번역:

Code:

새 직원 문서를 삽입해 보겠습니다.

직원 컬렉션을 만듭니다:

직원을 삽입합니다:

이 오류가 발생하고 괜찮습니다. 수동으로 수정할 수 있습니다.

그 이유를 읽고 예외입니다: value.intValue 유형의 문자열이 아닌 키 1을 삽입할 수 없습니다., 아! 키는 항상 문자열로 예상됩니다. insert_employee("1", "joe", "briggs", 10000) 가 효과가 있을 것이라고 기대하는 것은 직관적이지 않습니다. employee_id 를 문자열로 설정합니다.

생성된 코드를 변경해 보겠습니다:

그리고 UDF를 다시 생성합니다:

다시 삽입하려고 합니다:

직원을 업데이트합니다:

쏴! 직원 1이 조가 아니라 에밀리입니다. 

직원 1을 업데이트해 보겠습니다.

직원 보기

직원을 삭제합니다:

에밀리가 떠났습니다.

다시 생성된 코드에 오류가 발생했는데, 그 이유와 예외를 살펴보면 번역된 코드가 트랜잭션에서 삭제를 포함하지만 원본에서는 그렇지 않다는 것을 확인할 수 있습니다.

트랜잭션의 경우 버킷에는 다음이 필요합니다. 내구성 를 설정하려고 했지만 둘 이상의 데이터 서버가 필요하므로 오류가 발생했습니다.

여기서 해결 방법은 둘러싸는 번역을 제거하도록 코드를 변경하는 것입니다:

이제 원래 PL/SQL의 모든 함수는 JavaScript UDF를 통해 Couchbase에서 작동합니다. 예, 예제는 매우 사소하지만 도구를 사용하여 수동 감독을 거의 하지 않고도 PL/SQL 스크립트를 마이그레이션하는 방법에 대한 요점을 알 수 있습니다.

이 도구는 80%를 사용하도록 되어 있지만 나머지 20%는 여전히 사용자가 직접 수행해야 하지만 모든 코드를 직접 작성하는 것보다 훨씬 낫다는 것을 기억하세요!

미래

이 프로젝트는 오픈 소스이므로 자유롭게 기여해 주세요. 몇 가지 아이디어가 제안되었습니다:

    1. 생성된 코드를 비평하여 수동 개입이 전혀 필요하지 않도록 하는 비평 AI
    2. 현재 소스 코드는 작동만 하는 코드이며 병렬 처리나 코드 재사용에 대한 고려는 전혀 없었습니다.

또한 앞서 설명한 제한 사항도 포함됩니다.

리소스

마지막으로 저를 안내해준 카미니 자그티아니에게 감사의 말씀을 전하고 싶습니다. 피에르 레가조니 변환 도구를 테스트할 수 있도록 도와주셨습니다.

이 문서 공유하기
받은 편지함에서 카우치베이스 블로그 업데이트 받기
이 필드는 필수 입력 사항입니다.

작성자

게시자 가우라브 자야라즈 - 소프트웨어 엔지니어

가우라브 자야라즈는 카우치베이스 R&D의 쿼리 팀에서 인턴으로 근무하고 있습니다. Gaurav는 방갈로르의 PES 대학에서 컴퓨터 공학 학사 학위를 취득했습니다.

댓글 남기기

카우치베이스 카펠라를 시작할 준비가 되셨나요?

구축 시작

개발자 포털에서 NoSQL을 살펴보고, 리소스를 찾아보고, 튜토리얼을 시작하세요.

카펠라 무료 사용

클릭 몇 번으로 Couchbase를 직접 체험해 보세요. Capella DBaaS는 가장 쉽고 빠르게 시작할 수 있는 방법입니다.

연락하기

카우치베이스 제품에 대해 자세히 알고 싶으신가요? 저희가 도와드리겠습니다.