In this section you will find helper functions or procedures that are used to achieve functional equivalence of some Oracle features that are not supported natively in Snowflake Scripting.
The Cursor is simulated with an OBJECT with different information regarding the state of the cursor. A temporary table is created to store the result set of the cursor’s query.
Most of these Procedures return a new Object with the updated state of the cursor.
These procedures create a temporary table with the query of the cursor. An optional overload exists to support bindings.
CREATEORREPLACEPROCEDURE OPEN_BULK_CURSOR(CURSOROBJECT, BINDINGS ARRAY)RETURNSOBJECTLANGUAGEJAVASCRIPTEXECUTEASCALLERAS$$
var query = `CREATE OR REPLACE TEMPORARY TABLE ${CURSOR.NAME}_TEMP_TABLE AS ${CURSOR.QUERY}`;
snowflake.execute({ sqlText: query, binds: BINDINGS });
CURSOR.ROWCOUNT = 0;
CURSOR.ISOPEN = true;
return CURSOR;
$$;
CREATEORREPLACEPROCEDURE OPEN_BULK_CURSOR(CURSOROBJECT)RETURNSOBJECTLANGUAGESQLEXECUTEASCALLERAS$$
DECLARE
RESULT OBJECT;
BEGIN
RESULT := (CALL OPEN_BULK_CURSOR(:CURSOR, NULL));
RETURN :RESULT;
END;
$$;
Due to Oracle being capable of doing the FETCH statement on different kind of scenarios, multiple procedures with overloads were created to handle each case. These helpers save the fetched values into the RESULT property in the CURSOR object.
Some of the overloads include variations when the LIMIT clause was used or not. Other overloads have a COLUMN_NAMES argument that is necessary when the FETCH statement is being done into a variable that has or contains records with column names that are different to the column names of the query.
These procedures are used when the FETCH statement is done into one or multiple collections. Since the columns are specified in this FETCH operation, an override for specific COLUMN_NAMES is not necessary.
CREATEORREPLACEPROCEDURE FETCH_BULK_COLLECTIONS(CURSOROBJECT,LIMITFLOAT)RETURNSOBJECTLANGUAGEJAVASCRIPTEXECUTEASCALLERAS$$
var limitClause = '';
var limitValue = LIMIT ?? 'NULL';
var query = `SELECT * FROM ${CURSOR.NAME}_TEMP_TABLE LIMIT ${limitValue} OFFSET ${CURSOR.ROWCOUNT}`;
var stmt = snowflake.createStatement({ sqlText: query});
var resultSet = stmt.execute();
var column_count = stmt.getColumnCount();
CURSOR.RESULT = [];
for (let i = 0 ; i < column_count ; i++) {
CURSOR.RESULT[i] = [];
}
while (resultSet.next()) {
for (let i = 1 ; i <= column_count ; i++) {
let columnName = stmt.getColumnName(i);
CURSOR.RESULT[i - 1].push(resultSet.getColumnValue(columnName));
}
}
CURSOR.ROWCOUNT += stmt.getRowCount();
CURSOR.FOUND = stmt.getRowCount() > 0;
CURSOR.NOTFOUND = !CURSOR.FOUND;
return CURSOR;
$$;
CREATEORREPLACEPROCEDURE FETCH_BULK_COLLECTIONS(CURSOROBJECT)RETURNSOBJECTLANGUAGESQLEXECUTEASCALLERAS$$
DECLARE
RESULT OBJECT;
BEGIN
RESULT := (CALL FETCH_BULK_COLLECTIONS(:CURSOR, NULL));
RETURN :RESULT;
END;
$$;