SnowConvert: 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 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(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 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의 각 저장 프로시저에 포함된 내용에 따라 SnowConvert 는 그 안에 다음 Javascript 함수 중 1개 이상을 생성합니다.
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 헬퍼는 가져오기 함수를 사용하여 쿼리 결과에서 행을 가져옵니다. 가져오기 함수의 정의는 아래에 설명되어 있습니다.
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 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 없음.