Ad

Is If...exists Supported In Snowflake Stored Procedures?

I have written a stored procedure which will be called from python. The stored procedure needs to insert the variant data into my table if the id doesn't exist or update the existing variant data where there is a match for the id. The id will be passed the way the variant data is, but for now I am just trying to get it working with a hardcoded id. The stored procedure gets called successfully from python, but then nothing gets inserted or updated in the stored procedure and the stored procedure doesn't give me an error. I am not sure if I am doing something wrong or the...

if exists (select * from my_database_table where my_variant_data:id::varchar = '123456')

... part is being ignored because it isn't supported. I haven't been able to find anything in the documentation to prove or disprove this. Does anyone know?

create or replace procedure my_stored_procedure("variant_data" variant)
    returns string
    language javascript
    strict
    execute as owner
    as
    $$

var insert_update_query = `

if exists (select * from my_database_table where my_variant_data:id::varchar = '123456')
    begin
        update my_database_table SET my_variant_data = parse_json(:1)) WHERE my_variant_data:id::varchar = '123456'
    end
else
    begin
        insert into my_database_table(my_variant_data) select (parse_json(:1));
    end
`

var result = "";

    try {
        var sql_insert_update_query = snowflake.createStatement({
            sqlText: insert_update_query
        });
        var insert_update_query_result = sql_insert_update_query.execute();
        result += "\n Query succeeded";
    } catch (err) {
        result += "\n Query failed failed: " + err.code + "\n  State: " + err.state;
        result += "\n  Message: " + err.message;
        result += "\n Stack Trace:\n" + err.stackTraceTxt;
    }

    return result;
  
    $$
    ;

I have tested the insert and update parts of the query in the stored procedure individually and they work fine.

Insert - works as expected.

create or replace procedure my_stored_procedure("variant_data" variant)
returns string
language javascript
strict
execute as owner
as
$$


var sql_command = "insert into my_database_table(my_variant_data) select (parse_json(:1));";
var sql = snowflake.createStatement( {sqlText: sql_command, binds:[JSON.stringify(variant_data)]});
var resultSet = sql.execute();
return sql_command;
  
$$
;

Update - works as expected.

create or replace procedure my_stored_procedure("variant_data" variant)
    returns string
    language javascript
    strict
    execute as owner
    as
    $$

    var sql_command = "UPDATE my_database_table SET my_variant_data = parse_json(:1)) WHERE my_variant_data:id::varchar = '123456'";
    var sql = snowflake.createStatement( {sqlText: sql_command, binds:[JSON.stringify(variant_data)]});
    var resultSet = sql.execute();
      
    $$
    ;
Ad

Answer

Given the CODE executed needs to be valid runs on the console SQL, which this if is not, and it is fundamentally a MERGE command I would suggest flipping the code into a MERGE:

MERGE INTO my_database_table USING my_database_table 
    ON my_variant_data:id::varchar = '123456'
    WHEN MATCHED THEN UPDATE SET my_variant_data = parse_json(:1))
    WHEN NOT MATCHED THEN INSERT (my_variant_data) VALUES (parse_json(:1));

otherwise if you are want it in SP space, then I would be inclinded to break the code into a SELECT x INTO varaible FROM blar pattern and then have the IF be in SP and pick between the two blocks of SQL to run. But given it's just a merge, I would again still, do a merge.

Ad
source: stackoverflow.com
Ad