SnowConvert AI - Teradata - SnowConvert AI 프로시저 헬퍼¶
이 섹션에서는 Snowflake에서 기본적으로 지원되지 않는 일부 Teradata 기능의 기능적 동등성을 달성하기 위해 프로시저 내에서 사용되는 헬퍼 함수를 확인할 수 있습니다.
커서 도우미¶
이 섹션에서는 JavaScript에서 Teradata 커서의 기능적 동등성을 달성하기 위한 다양한 함수의 사용법을 설명합니다.
커서 도우미는 열기, 가져오기, 다음, 닫기 등 Teradata 커서가 수행하는 주요 네 가지 작업을 포함하는 함수입니다.
_CURSOR(),_는 필요한 변수를 선언하는 메인 루틴과 다른 하위 루틴을 선언합니다.
_OPEN(),_은 지정된 문을 실행하는 커서를 열고 필요한 변수를 업데이트합니다.
_NEXT(),_는 문의 다음 행(있는 경우)으로 커서를 이동하고 모든 열 값을 현재 행으로 설정합니다.
_FETCH(),_는 실행된 문의 응답에서 값(있는 경우)을 가져옵니다.
_CLOSE(),_는 _OUTQUERIES (EXEC 도우미에 추가된 경우)에서 임시 테이블을 제거하고 필요한 변수를 설정 해제합니다.
참고
출력 코드의 일부 부분은 명확성을 위해 생략되었습니다.
커서 샘플 사용법¶
Teradata
-- Additional Params: -t JavaScript
Replace procedure procedure1()
dynamic result sets 2
begin
-------- Local variables --------
declare sql_cmd varchar(20000) default ' ';
declare num_cols integer;
------- Declare cursor with return only-------
declare resultset cursor with return only for firststatement;
------- Declare cursor -------
declare cur2 cursor for select count(columnname) from table1;
-------- Set --------
set sql_cmd='sel * from table1';
-------- Prepare cursor --------
prepare firststatement from sql_cmd;
-------- Open cursors --------
open resultset;
open cur1;
-------- Fetch -------------
fetch cur1 into val1, val2;
-------- Close cursor --------
close cur1;
end;
Snowflake 출력
CREATE OR REPLACE PROCEDURE procedure1 ()
RETURNS STRING
LANGUAGE JAVASCRIPT
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"teradata"}}'
EXECUTE AS CALLER
AS
$$
// SnowConvert AI Helpers Code section is omitted.
//------ Local variables --------
var SQL_CMD = ` `;
var NUM_COLS;
var RESULTSET = new CURSOR(() => FIRSTSTATEMENT,[],true);
//----- Declare cursor -------
var CUR2 = new CURSOR(`SELECT
COUNT(columnname)
from
table1`,[],false);
//------ Set --------
SQL_CMD = `SELECT
* from
table1`;
//------ Prepare cursor --------
var FIRSTSTATEMENT = SQL_CMD;
//------ Open cursors --------
RESULTSET.OPEN();
CUR1.OPEN();
//------ Fetch -------------
CUR1.FETCH() && ([val1,val2] = CUR1.INTO());
//------ Close cursor --------
CUR1.CLOSE();
return PROCRESULTS();
$$;
커서 도우미 함수 정의¶
var CURSOR = function (stmt,binds,withReturn) {
var rs, rows, row_count, opened = false, resultsetTable = '', self = this;
this.CURRENT = new Object;
this.INTO = function () {
return self.res;
};
this.OPEN = function (usingParams) {
try {
if (usingParams) binds = usingParams;
if (binds instanceof Function) binds = binds();
var finalBinds = binds && binds.map(fixBind);
var finalStmt = stmt instanceof Function ? stmt() : stmt;
if (withReturn) {
resultsetTable = EXEC(finalStmt,finalBinds,true,null,{
temp : true
});
finalStmt = `SELECT * FROM TABLE(RESULT_SCAN('${resultsetTable}'))`;
finalBinds = [];
}
rs = snowflake.createStatement({
sqlText : finalStmt,
binds : finalBinds
});
rows = rs.execute();
row_count = rs.getRowCount();
ACTIVITY_COUNT = rs.getRowCount();
opened = true;
return this;
} catch(error) {
ERROR_HANDLERS && ERROR_HANDLERS(error);
}
};
this.NEXT = function () {
if (row_count && rows.next()) {
this.CURRENT = new Object;
for(let i = 1;i <= rs.getColumnCount();i++) {
(this.CURRENT)[rs.getColumnName(i)] = rows.getColumnValue(i);
}
return true;
} else return false;
};
this.FETCH = function () {
self.res = [];
self.res = fetch(row_count,rows,rs);
if (opened) if (self.res.length > 0) {
SQLCODE = 0;
SQLSTATE = '00000';
} else {
SQLCODE = 7362;
SQLSTATE = '02000';
var fetchError = new Error('There are not rows in the response');
fetchError.code = SQLCODE;
fetchError.state = SQLSTATE;
if (ERROR_HANDLERS) ERROR_HANDLERS(fetchError);
} else {
SQLCODE = 7631;
SQLSTATE = '24501';
}
return self.res && self.res.length > 0;
};
this.CLOSE = function () {
if (withReturn && _OUTQUERIES.includes(resultsetTable)) {
_OUTQUERIES.splice(_OUTQUERIES.indexOf(resultsetTable),1);
}
rs = rows = row_count = undefined;
opened = false;
resultsetTable = '';
};
};
알려진 문제 ¶
문제가 발견되지 않았습니다.
Exec Helper¶
exec 헬퍼는 프로시저의 SQL 문을 실행하는 데 사용되는 함수입니다.
구문¶
EXEC(stmt)
EXEC(stmt, binds)
EXEC(stmt, binds, noCatch)
EXEC(stmt, binds, noCatch, catchFunction)
EXEC(stmt, binds, noCatch, catchFunction, opts)
매개 변수¶
stmt¶
실행할 SQL 문의 문자열입니다.
바인딩(선택 사항)¶
SQL 문에 바인딩할 값 또는 변수가 포함된 배열입니다.
NoCatch (선택 사항)¶
부울 값으로 오류가 잡히지 않아야 하는지 여부를 결정합니다.
catchFunction(선택 사항)¶
실행 함수 실행 중 오류가 발생할 경우 실행하는 함수입니다.
옵션(선택 사항)¶
JSON 오브젝트({ temp : true })를 사용하여 ID 쿼리가 반환되어야 하는지 확인합니다.
FixBind 및 FormatDate 함수¶
Exec Helper는 FixBind 라는 도우미에 정의된 함수를 사용합니다. 이 함수는 바인딩 변수 중 하나가 날짜 유형인 경우 FormatDate 함수를 사용하는데, 이는 Snowflake에서 날짜 유형을 올바르게 관리하기 위한 것입니다.\ 두 함수는 아래와 같이 정의되어 있습니다.
var formatDate = (arg) => (new Date(arg - (arg.getTimezoneOffset() * 60000))).toISOString().slice(0,-1);
var fixBind = function (arg) {
arg = arg == undefined ? null : arg instanceof Date ? formatDate(arg) : arg;
return arg;
};
참고
출력 코드의 일부 부분은 명확성을 위해 생략되었습니다.
Exec 사용법 샘플¶
Teradata
-- Additional Params: -t JavaScript
REPLACE PROCEDURE ProcedureSample ()
BEGIN
case value
when 0 then
select * from table1
else
update table1 set name = "SpecificValue" where id = value;
end case
END;
Snowflake 출력
CREATE OR REPLACE PROCEDURE ProcedureSample ()
RETURNS STRING
LANGUAGE JAVASCRIPT
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"teradata"}}'
EXECUTE AS CALLER
AS
$$
// SnowConvert AI Helpers Code section is omitted.
switch(value) {
case 0:EXEC(`SELECT * from table1`,[]);
break;
default:EXEC(`UPDATE table1
set
name = "SpecificValue"
where
id = value`,[]);
break;
}
$$;
Exec Helper 정의¶
var EXEC = function (stmt,binds,noCatch,catchFunction,opts) {
try {
binds = binds ? binds.map(fixBind) : binds;
_RS = snowflake.createStatement({
sqlText : stmt,
binds : binds
});
_ROWS = _RS.execute();
ROW_COUNT = _RS.getRowCount();
ACTIVITY_COUNT = _RS.getNumRowsAffected();
HANDLE_NOTFOUND && HANDLE_NOTFOUND(_RS);
if (INTO) return {
INTO : function () {
return INTO();
}
};
if (_OUTQUERIES.length < DYNAMIC_RESULTS) _OUTQUERIES.push(_ROWS.getQueryId());
if (opts && opts.temp) return _ROWS.getQueryId();
} catch(error) {
MESSAGE_TEXT = error.message;
SQLCODE = error.code;
SQLSTATE = error.state;
var msg = `ERROR CODE: ${SQLCODE} SQLSTATE: ${SQLSTATE} MESSAGE: ${MESSAGE_TEXT}`;
if (catchFunction) catchFunction(error);
if (!noCatch && ERROR_HANDLERS) ERROR_HANDLERS(error); else throw new Error(msg);
}
};
알려진 문제 ¶
문제가 발견되지 않았습니다.
관련 EWIs ¶
관련 EWIs 없음.
함수 동등성 도우미¶
여러 Teradata 언어 기능을 더 잘 지원하기 위해 SnowFlake의 프로시저에서 사용할 수 있는 JavaScript의 헬퍼 함수 목록이 제공됩니다.
Teradata의 각 저장 프로시저에 있는 내용에 따라, SnowConvert AI는 내부에 다음 자바스크립트 함수 중 하나 이상을 생성합니다.
CompareDates¶
무효 처리 날짜를 비교하는 함수입니다. Javascript에서는 날짜 비교를 위해 _.getTime()_을 호출해야 합니다.
var CompareDates = function(value1, value2) {
var value1Time = value1 && value1.getTime() || null;
var value2Time = value2 && value2.getTime() || null;
if (value1Time == null && value2Time == null) return null; /*in SQL null == null is equal to null as well as any other comparison */
return value1Time > value2Time? 1 : value1Time<value2Time? -1 : 0;
}
BetweenFunc¶
Teradata에서 BETWEEN 문을 처리하는 함수입니다.
var BetweenFunc = function (expression,startExpr,endExpr) {
if ([expression,startExpr,endExpr].some((arg) => arg == null)) {
return false;
}
return expression >= startExpr && expression <= endExpr;
};
LikeFunction()¶
Teradata에서 LIKE 문을 처리하는 함수입니다.
var likeFunction = function (leftExpr,rightExpr) {
RegExp.escape = function (text) {
if (!arguments.callee.sRE) {
var specials = ['/','.','*','+','?','|','(',')','[',']','{','}','\\'];
arguments.callee.sRE = new RegExp('(\\' + specials.join('|\\') + ')','g');
}
return text.replace(arguments.callee.sRE,'\\$1');
}
var likeExpr = RegExp.escape(rightExpr);
var likeResult = new RegExp(likeExpr.replace('%','.*').replace('_','.')).exec(leftExpr) != null;
return likeResult;
};
ERROR_HANDLERS()¶
주요 오류 처리 루틴입니다.
var continue_handler_1 = function (error) {
{
V_SQL_VALUE = SQLSTATE;
V_EXCEPTION_FLAG = `Y`;
}
};
// Main error-handling routine
var ERROR_HANDLERS = function (error) {
switch(error.state) {
//Conversion Warning - handlers for the switch default (SQLWARNING/SQLEXCEPTION/NOT FOUND) can be the following
default:continue_handler_1(error);
}
};
INSERT_TEMP¶
경고
_ 이 도우미는 버전 2.0.15부터 저장 프로시저에서 더 이상 사용되지 않습니다. _
지정된 _parameters_와 함께 query 인자를 사용하여 임시 테이블을 생성하는 함수입니다.
var procname = `PUBLIC.Procedure1`;
var temptable_prefix, tablelist = [];
var INSERT_TEMP = function (query,parameters) {
if (!temptable_prefix) {
var sql_stmt = `select current_session() || '_' || to_varchar(current_timestamp, 'yyyymmddhh24missss')`;
var rs = snowflake.createStatement({
sqlText : sql_stmt,
binds : []
}).execute();
temptable_prefix = rs.next() && (procname + '_TEMP_' + rs.getColumnValue(1) + '_');
}
var tablename = temptable_prefix + tablelist.length;
tablelist.push(tablename);
var sql_stmt = `CREATE OR REPLACE TEMPORARY TABLE ${tablename} AS ${query}`;
snowflake.execute({
sqlText : sql_stmt,
binds : parameters
});
return tablename;
};
IS_NOT_FOUND()¶
SELECT 가 반환 값이 없거나 문장이 0 행에 영향을 미치는 경우 유효성을 검사하는 함수입니다. 이는 NOT FOUND EXCEPTIONS 에 대한 종료 또는 계속 처리기가 있을 때 Teradata와 동일한 동작을 에뮬레이션하기 위해 수행됩니다.
let IS_NOT_FOUND = (stmt) => {
let n = -1;
let cmd = stmt.getSqlText().replace(new RegExp("\\/\\*.*\\*\\/","gsi"),"").replace(new RegExp("--.*?\\n","gsi"),"");
let matched = cmd.match(new RegExp("\\s*(\\w+)\\s+"),"");
if (matched) {
cmd = matched[1].toUpperCase();
switch(cmd) {
case "CALL":
case "DROP":
case "CREATE":
case "ALTER":
case "SELECT":
n = stmt.getRowCount();
break;
default:n = stmt.getNumRowsAffected();
break;
}
}
return n == 0;
};
HANDLE_NOTFOUND()¶
이 함수는 위의 IS_NOT_FOUND 함수를 사용하여 인위적인 오류 ‘NOT FOUND’를 throw할 때 유효성을 검사합니다.
let HANDLE_NOTFOUND = (stmt) => {
if (IS_NOT_FOUND(stmt) && (error = new Error('NOT_FOUND')) && (NOT_FOUND = true) && ([error.code,error.state] = ['020000','020000'])) throw error;
};
PROCRESULTS()¶
0 또는 여러 개의 출력 매개 변수를 받아 배열에 _OUTQUERIES 로 바인딩하여 반환하는 함수입니다.
let PROCRESULTS = (...OUTPARAMS) => JSON.stringify([...OUTPARAMS,[..._OUTQUERIES]]);
알려진 문제 ¶
문제가 발견되지 않았습니다.
관련 EWIs ¶
관련 EWIs 없음.
헬퍼로¶
into 함수는 하위 쿼리 또는 select into 문에서 결과 행을 추출하는 데 사용됩니다.
가져오기 함수¶
INTO 헬퍼는 가져오기 함수를 사용하여 쿼리 결과에서 행을 가져옵니다. 가져오기 함수의 정의는 아래에 설명되어 있습니다.
var fetch = (count,rows,stmt) =>
(count && rows.next() && Array.apply(null,Array(stmt.getColumnCount())).map((_,i)
=> rows.getColumnValue(i + 1))) || [];
참고
출력 코드의 일부 부분은 명확성을 위해 생략되었습니다.
샘플 사용법 살펴보기¶
Teradata
-- Additional Params: -t JavaScript
REPLACE PROCEDURE SubQuerypoc ()
BEGIN
DECLARE monat INTEGER;
SET monat = (SELECT column1
FROM table1);
END;
Snowflake 출력
CREATE OR REPLACE PROCEDURE SubQuerypoc ()
RETURNS STRING
LANGUAGE JAVASCRIPT
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"teradata"}}'
EXECUTE AS CALLER
AS
$$
// SnowConvert AI Helpers Code section is omitted.
var MONAT;
EXEC(`(SELECT column1 FROM table1)`,[]);
var subQueryVariable0;
[subQueryVariable0] = INTO();
MONAT = subQueryVariable0;
$$;
헬퍼 함수 정의¶
var INTO = () => fetch(ROW_COUNT,_ROWS,_RS);
알려진 문제 ¶
문제가 발견되지 않았습니다.
관련 EWIs ¶
관련 EWIs 없음.