'Snowflake - How to call a UDF within a Procedure
In the following, TEST_DATA is my data and TEST_VALIDATE is the table I am validating against. I want to test TEST_DATA.DVALUE against TEST_VALIDATE and adjust the DVALUE such that it is always within a given range. The UDF TEST_RANGE() does this and returns the adjusted buffered value:
CREATE TABLE TEST_DATA
(
MNEMONIC VARCHAR2(3),
DVALUE NUMBER(5,1)
);
INSERT INTO TEST_DATA ( MNEMONIC, DVALUE ) VALUES ( 'AT', 2 );
INSERT INTO TEST_DATA ( MNEMONIC, DVALUE ) VALUES ( 'BP', 88 );
CREATE TABLE TEST_VALIDATE
(
MNEMONIC VARCHAR2(3),
MINIMUM_VALUE NUMBER(5,1),
MAXIMUM_VALUE NUMBER(5,1)
);
INSERT INTO TEST_VALIDATE ( MNEMONIC, MINIMUM_VALUE, MAXIMUM_VALUE ) VALUES ( 'AT', 5.1, 10.1 );
INSERT INTO TEST_VALIDATE ( MNEMONIC, MINIMUM_VALUE, MAXIMUM_VALUE ) VALUES ( 'BP', 2.2, 100.2 );
CREATE OR REPLACE FUNCTION TEST_RANGE( p_mnemonic VARCHAR2, p_reading NUMBER(5,1) )
RETURNS NUMBER AS
'SELECT
MAX(CASE
WHEN p_reading BETWEEN MINIMUM_VALUE AND MAXIMUM_VALUE THEN p_reading
WHEN p_reading < MINIMUM_VALUE THEN MINIMUM_VALUE
WHEN p_reading > MAXIMUM_VALUE THEN MAXIMUM_VALUE
ELSE NULL
END)
FROM TEST_VALIDATE
WHERE MNEMONIC = p_mnemonic';
This test executes fine:
SELECT TEST_RANGE( 'AT', 55 );
but this attracts the following error "002031 (42601): SQL compilation error: Unsupported subquery type cannot be evaluated" -- WHY:
SELECT TEST_RANGE( MNEMONIC, DVALUE ) FROM TEST_DATA;
So I thought of creating a Stored Procedure to do this, but how do you call a UDF in a Procedure? I thought this was pretty basic but I can't find any post on it. Do I have to wrap the UDF in a createStatement().execute().getColumnValue() routine? Is there a more readable way than this?
CREATE OR REPLACE PROCEDURE EDW_WEATHER.TEST_SP ()
RETURNS VARIANT
LANGUAGE JAVASCRIPT
AS $$
var rs = snowflake.createStatement( { sqlText: `SELECT MNEMONIC, DVALUE FROM TEST_DATA`, binds:[] } ).execute();
var results_array = [];
while (rs.next()) {
// This is wrong. How do I call the UDF???
results_array.push( rs.select( TEST_RANGE( rs.getColumnValue('MNEMONIC'), rs.getColumnValue('DVALUE') ) ) );
}
return results_array;
$$
Solution 1:[1]
To answer your last question how you call a UDF within a Stored Procedure: You can trigger the UDF the same way you do outside the SP.
You have to use the .execute()-method, trigger a SELECT myUDF() with it and then retrieve the resultset for further consumption & processing.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Marcel |
