SnowConvert: Teradata Prozeduren-Hilfsfunktionen¶
Cursor-Hilfsfunktion¶
Die Cursor-Hilfsfunktion ist eine Funktion, die die vier wichtigsten Aktionen enthält, die Teradata-Cursor ausführen, z. B. Öffnen, Abrufen, Weiter und Schließen.
CURSOR(),_ die Hauptroutine, die die benötigten Variablen und andere Unterprogramme deklariert.
OPEN(),_ öffnet den Cursor, der die angegebene Anweisung ausführt, und aktualisiert die erforderlichen Variablen.
NEXT(),_ bewegt den Cursor in die nächste Zeile (falls vorhanden) der Anweisung und setzt jeden Spaltenwert auf die aktuelle Zeile.
FETCH(),_ holt sich die Werte (falls vorhanden) aus der Antwort der ausgeführten Anweisung.
CLOSE(),_ entfernt die temporäre Tabelle aus demOUTQUERIES (wenn sie in der EXEC-Hilfsfunktion hinzugefügt wurde) und setzt die notwendigen Variablen zurück.
Bemerkung
Einige Teile des Ausgabecodes werden aus Gründen der Übersichtlichkeit weggelassen.
Cursor-Verwendungsbeispiel¶
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-Ausgabe
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();
$$;
Definition der Cursor-Hilfsfunktion¶
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 = '';
};
};
Bekannte Probleme ¶
Es wurden keine Probleme gefunden.
Exec-Hilfsfunktion¶
Syntax¶
EXEC(stmt)\ EXEC(stmt, binds)\ EXEC(stmt, binds, noCatch)\ EXEC(stmt, binds, noCatch, catchFunction)\ EXEC(stmt, binds, noCatch, catchFunction, opts)
Parameter¶
stmt¶
Die Zeichenfolge der auszuführenden SQL Anweisung.
Binds (optional)¶
Ein Array mit den Werten oder den Variablen, die in die Anweisung SQL eingebunden werden sollen.
NoCatch (optional)¶
Boolescher Wert, um zu wissen, ob ein Fehler nicht abgefangen werden soll.
catchFunction (optional)¶
Eine Funktion, die ausgeführt wird, wenn bei der Ausführung der exec-Funktion ein Fehler auftritt.
Opts (optional)¶
Ein JSON-Objekt ({ temp : true }), um zu wissen, ob die Abfrage ID zurückgegeben werden soll.
FixBind- und FormatDate-Funktionen¶
Die Exec-Hilfsfunktion verwendet eine in den Hilfsfunktionen definierte Funktion namens FixBind. Diese Funktion verwendet die Funktion FormatDate, wenn sie feststellt, dass eine der Bindungsvariablen ein Datumstyp ist. Dies geschieht, um die Datumstypen in Snowflake richtig zu verwalten.
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;
};
Bemerkung
Einige Teile des Ausgabecodes werden aus Gründen der Übersichtlichkeit weggelassen.
Exec-Verwendungsbeispiel¶
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-Ausgabe
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;
}
$$;
Definition der Exec-Hilfsfunktion¶
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);
}
};
Bekannte Probleme ¶
Es wurden keine Probleme gefunden.
Zugehörige EWIs ¶
Keine zugehörigen EWIs.
Funktionsäquivalenz-Hilfsfunktion¶
Je nachdem, was in den einzelnen gespeicherten Prozeduren in Teradata enthalten ist, erstellt SnowConvert eine oder mehrere der folgenden Javascript-Funktionen in ihnen.
CompareDates¶
Eine Funktion, die Datumsangaben vergleicht, die mit Nullen umgehen. In Javascript ist es erforderlich, .getTime() für Datumsvergleiche aufzurufen.
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¶
Eine Funktion zur Handhabung der BETWEEN Anweisung in Teradata.
var BetweenFunc = function (expression,startExpr,endExpr) {
if ([expression,startExpr,endExpr].some((arg) => arg == null)) {
return false;
}
return expression >= startExpr && expression <= endExpr;
};
LikeFunction()¶
Eine Funktion zur Handhabung der LIKE Anweisung in Teradata.
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()**_¶
Die wichtigste Routine zur Fehlerbehandlung.
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**_¶
Warnung
Diese Hilfsfunktion ist in gespeicherten Prozeduren seit Version 2.0.15 veraltet. _
Eine Funktion zur Erstellung einer temporären Tabelle unter Verwendung des Arguments query mit den angegebenen parameters.
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()**_¶
Eine Funktion, die validiert, wenn SELECT keine Werte zurückgibt oder ein Satz null Zeilen betrifft. Dies geschieht, um die gleiche Verhaltensweise wie bei Teradata zu emulieren, wenn es Exits oder Continue-Handler für NOT FOUND EXCEPTIONS gibt.
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()**_¶
Diese Funktion verwendet die obige IS_NOT_FOUND Funktion, um zu überprüfen, wann ein künstlicher Fehler ‚NOT FOUND‘ ausgelöst wird.
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()¶
Eine Funktion, die null oder mehrere Ausgabeparameter annimmt und sie mit demOUTQUERIES in einem Array verbindet, um zurückgegeben zu werden.
let PROCRESULTS = (...OUTPARAMS) => JSON.stringify([...OUTPARAMS,[..._OUTQUERIES]]);
Bekannte Probleme ¶
Es wurden keine Probleme gefunden.
Zugehörige EWIs ¶
Keine zugehörigen EWIs.
Into-Hilfsfunktion¶
Abruffunktion¶
Die Hilfsfunktion INTO verwendet eine Abruffunktion, um die Zeile aus einer Abfrage abzurufen. Die Definition der Abruffunktion wird im Folgenden beschrieben.
var fetch = (count,rows,stmt) =>
(count && rows.next() && Array.apply(null,Array(stmt.getColumnCount())).map((_,i)
=> rows.getColumnValue(i + 1))) || [];
Bemerkung
Einige Teile des Ausgabecodes werden aus Gründen der Übersichtlichkeit weggelassen.
Into-Verwendungsbeispiel¶
Teradata
-- Additional Params: -t JavaScript
REPLACE PROCEDURE SubQuerypoc ()
BEGIN
DECLARE monat INTEGER;
SET monat = (SELECT column1
FROM table1);
END;
Snowflake-Ausgabe
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;
$$;
Definition der Into-Hilfsfunktion¶
var INTO = () => fetch(ROW_COUNT,_ROWS,_RS);
Bekannte Probleme ¶
Es wurden keine Probleme gefunden.
Zugehörige EWIs ¶
Keine zugehörigen EWIs.