Capturing the o/p of "execute immediate" to a variable - snowflake-cloud-data-platform

I have the need to capture the o/p of "execute immediate" statement and use that o/p variable in incremental steps execution of the proc.
Like the code is :
var_01 := 'SELECT COUNT(1) AS cnt FROM ALL_RESOURCE_MONITOR_MASTER WHERE' || ' '
|| 'account_name = ' ||''''|| lv_acct_name_new ||''''|| ' ' || 'AND' || ' '
|| 'rm_type= ' ||''''|| type || ''''||' ' || 'AND' || ' '
|| 'env= ' ||''''|| env || ''''||' ';
cnt := (execute immediate :var_01);
Now post I get the cnt as populated, then I need to run the below if~else statement:
if (cnt > 0) then
return 'execute the statement';
else
return 'Resource monitor already present hence insert skipped';
end if;
But the problem is when I try to execute this block I am always getting an error like :
SQL compilation error: Invalid expression value (?SqlExecuteImmediateDynamic?) for assignment.
Please do provide your inputs on resolving this. Thanks in advance!!

Unfortunately there is no syntax like EXECTUE <sql> INTO <output_variable_list> USING <input_variable_list> known from different dialects.
EXECUTE IMMEDIATE:
Executes a string that contains a SQL statement or a Snowflake Scripting statement.
EXECUTE IMMEDIATE '<string_literal>'
[ USING (bind_variable_1 [, bind_variable_2 ...] ) ] ;
In this scenario there is no need to use dynamic SQL for checking in metadata table as it could be rewritten to use parametrized if-statement:
CREATE OR REPLACE TABLE ALL_RESOURCE_MONITOR_MASTER
AS
SELECT 'acc1' AS account_name, 'TEST' AS env, 'WAREHOUSE' AS rm_type;
Code:
DECLARE
lv_acct_name_new TEXT := 'acc1';
type TEXT := 'WAREHOUSE';
env TEXT := 'TEST';
BEGIN
IF (EXISTS (SELECT 1
FROM ALL_RESOURCE_MONITOR_MASTER
WHERE account_name = :lv_acct_name_new
AND rm_type = :type
AND env = :env
)) THEN
RETURN 'Executing some code';
ELSE
RETURN 'Resource monitor already present hence insert skipped';
END IF;
END;

Related

Snowflake stored procedure input parameter

I want to form a SQL construct using a stored procedure which would have email_id passed as a variable i.e., "v_created_by" as one of the input parameter.
My code skeleton looks like :
create or replace procedure testing_proc(type varchar, ..., ..., ..., v_created_by varchar)
returns varchar not null
....,
....,
begin
wh_setup := 'CREATE OR REPLACE WAREHOUSE' || ' ' || wh_name || ' ' || 'WITH' || ' '
|| 'WAREHOUSE_SIZE = ' || v_wh_size || ' '
...
...
|| 'SCALING_POLICY= ' || 'STANDARD' || ' '
|| 'COMMENT=' || v_created_by;
execute immediate wh_setup;
return 'successfully created the warehouse :' || ' ' || wh_name;
end;
Whenever I am calling the proc like :
call testing_proc('STD','EDWQA','ANALYST','XSMALL','1','1',300,'somen.swain#GMAIL.COM')
I get the error as :
"Uncaught exception of type 'STATEMENT_ERROR' on line 15 at position 2 :
SQL compilation error: syntax error line 1 at position 199 unexpected '#GMAIL.COM'.
syntax error line 1 at position 199 unexpected '#GMAIL.COM'.
Reference SQL which I am trying to create via procedure is given below:
CREATE WAREHOUSE IF NOT EXISTS dbt_workload
WITH WAREHOUSE_SIZE = 'XSMALL'
WAREHOUSE_TYPE = 'STANDARD'
SCALING_POLICY = 'STANDARD'
COMMENT = '"created for testing"';
Please see the COMMENT keyword over here where it can be used as a tag.
Any pointers on how to address this to ensure I can use this email_id and pass it with comment section would really help.
The comment has to be wrapped with ' as it requires string literal:
COMMENT = '<string_literal>'
Instead:
|| 'COMMENT=' || v_created_by;
to:
|| 'COMMENT=''' || v_created_by || ''';
The input should be validated/trusted before passing it to be run.

How can I pass variable to sqlplus script and use same variable as table-prefix in Oracle query?

I am having following sql script namely check_and_create_tbl.sql
DECLARE
t_count NUMBER;
BEGIN
SELECT count(*) into t_count FROM all_objects WHERE object_name = '&1_EMPLOYEE' AND object_type = 'TABLE';
if t_count <= 0 then
execute immediate 'CREATE TABLE ' || &1 || '_EMPLOYEE (
ID NUMBER(3)
, NAME VARCHAR2(30) NOT NULL
)';
end if;
END;
Now I am calling above script in my bash program's function like below.
function exe_orcl {
exe_command+=("/opt/bin/sqlplus -s <ORCL_USER>/<ORCL_PASS>#(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=<ORCL_HOST>)(PORT=<ORCL_PORT>)))(CONNECT_DATA=(SERVICE_NAME=<ORCL_SNAME>))) ")
while (( $# > 0 )); do
exe_command+=("$1")
shift 1
done
echo "SQLPLUS command = ${_cmd[#]}"
"${exe_command[#]}" && { echo "SQLPLUS Success"; } || { echo "SQLPLUS Failed"; }
}
function exe_orcl_sql_file {
sql_file=$1
prefix="TBL_SALE"
shift 1
exe_orcl << EOF
whenever oserror exit 9;
whenever sqlerror exit SQL.SQLCODE;
SET NEWPAGE NONE
#${sql_file} ${prefix} ${#};
exit
EOF
}
Now in my bash program I try to execute sql file like below.
exe_orcl_sql_file "/tmp/check_and_create_tbl.sql" || { echo "SQLPLUS execution error"; }
I am seeing the log as below.
SQLPLUS command = /opt/bin/sqlplus -s XXXX/XXXX#(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=XXXX)(PORT=XXXX)))(CONNECT_DATA=(SERVICE_NAME=XXXX)))
SQLPLUS Success
But I do not see the TBL_SALE_EMPLOYEE created in Oracle DB, please guide me as to what am i missing here?
You need to remember that the variable is input by sql*plus, you also have to realise that '_' is a valid part of a variable name so you need to clearly point out where the end should be.
DECLARE
t_count NUMBER;
BEGIN
SELECT count(*) into t_count FROM all_objects WHERE object_name = '&1._EMPLOYEE' AND object_type = 'TABLE';
if t_count <= 0 then
execute immediate 'CREATE TABLE &1._EMPLOYEE (
ID NUMBER(3)
, NAME VARCHAR2(30) NOT NULL
)';
end if;
END;
/

Netezza error store procedure error

I try to execute a stored procedure and I have the following issue.
I don't know if I have a problem with the format of the string.
This is my error message:
ERROR: unexpected error 12 in EXECUTE of query 'MERGE INTO GTN..ON_ORDER_REPORT_TSS_TEST a
USING QUANTISENSE_PROD_STAGE..VW_CURRENT_VIEW_OF_LINE_SHEET_HIST b
ON TRIM(a.channel) = TRIM(upper(b.channel_desc))
and TRIM(a.style_colour) = TRIM(b.style_opt_numb)
and TRIM(a.season_code) = TRIM(b.season_cd)
and a.STYLE_COLOUR = 'IG1501S-034121'
WHEN MATCHED THEN
UPDATE SET a.REVISED_IN_STORE_DT = b.REVISED_IN_STORE_DT || ' 00:00:00',
a.PLANNED_IN_STORE_DT = b.PLANNED_IN_STORE_DT || ' 00:00:00';'
This is the code of my stored procedure:
CREATE OR REPLACE PROCEDURE USP_UPDATE_LINE_SHEET_TEST(CHARACTER VARYING(ANY))
RETURNS CHARACTER VARYING(ANY)
LANGUAGE NZPLSQL AS
BEGIN_PROC
DECLARE
TABLENAME ALIAS FOR $1;
SQL TEXT;
SQLFULL varchar(4000);
BEGIN
SQL := 'MERGE INTO GTN..'||TABLENAME||' a
USING QUANTISENSE_PROD_STAGE..VW_CURRENT_VIEW_OF_LINE_SHEET_HIST b
ON TRIM(a.channel) = TRIM(upper(b.channel_desc))
and TRIM(a.style_colour) = TRIM(b.style_opt_numb)
and TRIM(a.season_code) = TRIM(b.season_cd)
and a.STYLE_COLOUR = ''IG1501S-034121''
WHEN MATCHED THEN
UPDATE SET a.REVISED_IN_STORE_DT = b.REVISED_IN_STORE_DT || '' 00:00:00'',
a.PLANNED_IN_STORE_DT = b.PLANNED_IN_STORE_DT || '' 00:00:00'';';
EXECUTE IMMEDIATE SQL;
END;
END_PROC;
What can I do to fix this error?

Postgresql: Array value must start with "{" or dimension information

CREATE OR REPLACE FUNCTION f_old_transactions (IN p_fromdate date, IN p_todate date, IN p_transtype varchar,IN OUT p_cancelled boolean,
OUT p_transaction_date date,
OUT p_type varchar,
OUT p_description varchar,
OUT p_amount numeric)
RETURNS SETOF record AS
$BODY$
declare lRunQuery text;
declare lTotalRec record;
declare lBranchList text[];
declare lTranstype text[];
BEGIN
select into lTranstype
dt.type
from
v_data_types dt;
lTranstype := regexp_split_to_array(p_transtype, ',');
lrunquery := 'select
it.transaction_date trandate,
dt.type,
it.description,
ita.amount,
it.cancelled
from
import_transaction it
inner join import_transaction_account ita on it.import_transaction_id=ita.import_transaction_id
where
it.transaction_date >= ' || quote_literal(p_fromdate) || '
and it.transaction_date <= ' || quote_literal(p_todate) || '
and dt.type = any(' || quote_literall(p_transtype) || ') and';
if (p_cancelled = TRUE) then
lrunquery := lrunquery || '
it.cancelled = ' || quote_literal(p_cancelled) || '';
else
lrunquery := lrunquery || '
it.cancelled = ' || quote_literal(p_cancelled) || '';
end if;
FOR lTotalrec in
execute lRunQuery
LOOP
p_transaction_date := ltotalrec.trandate;
p_type :=ltotalrec.type;
p_description :=ltotalrec.description;
p_amount :=ltotalrec.amount;
p_cancelled := ltotalrec.cancelled;
return next;
END LOOP;
return ;
end;
$BODY$
LANGUAGE plpgsql IMMUTABLE
COST 100
ROWS 1000;
ALTER FUNCTION f_old_transactions(date,date,varchar,boolean) OWNER TO "CompuLoanPostgres";
select * from f_old_transactions ('01-Jan-2010','31-Dec-2018','Receipt Cash','FALSE')
I'm getting an error that my array value must start with "{". My array I'm trying to create is from a view v_data_type the view consist of only one column with a varchar type.
Can anyone please direct me where the issue in my code is?
Thank you in advance
I don't think you've given us enough information to know for certain what's going wrong. Notably, I have no idea what the tables should look like, either in schema or content. Without that, I can't build a test case in my own DB to debug.
That said, I noticed a couple things, specifically around the lTranstype variable:
You're assigning lTranstype twice. First you SELECT INTO it, and then you immediately assign it to a value unpacked from the p_transtype argument. It's not clear to me what you want in that variable.
When constructing your query later, you include and dt.type = any(' || quote_literall(p_transtype) || '). The problem is that p_transtype is a varchar argument, and you're trying to access it like an array. I suspect you want that to read and dt.type = any(' || quote_literall(lTranstype) || '), but I could be mistaken.
I'm guessing that your type error is coming from that second problem, but it seems like you need to reassess what the different variables in this function are intended for. Good luck.

having issues with single quotes using like 'string token' in execute immediate statement

Here is the section of code, I am using ' ' blah ' ' to escape single quotes but I guess its not working:
declare
my_func varchar2(20) :='test_func';
begin
execute immediate 'insert into TABLE_TEST (OUTPUT) select ' || my_func || ' from dual where TABLE_TEST.FUNCTION_NAME like ' 'VALIDATION1_%' ' ';
end;
I am getting the following error:
PLS-00103: Encountered the symbol "VALIDATION1_%" when expecting one of the following:
& = - + ; < / > at in is mod remainder not rem return
returning <an exponent (**)> <> or != or ~= >= <= <> and or
like like2 like4 likec between into using || bulk member
submultiset
The symbol "* was inserted before "VALIDATION1_%" to continue.
It looks like you are trying to escape the single quote with another single quote (which is good), but there is an extra space in between the two. That has to go.
Change
' from dual where TABLE_TEST.FUNCTION_NAME like ' 'VALIDATION1_%' ' '
to
' from dual where TABLE_TEST.FUNCTION_NAME like ''VALIDATION1_%'' '
In cases like this it's much simpler to use the new q syntax for literal strings, e.g.:
execute immediate 'insert into TABLE_TEST (OUTPUT) select ' || my_func ||
q[' from dual where TABLE_TEST.FUNCTION_NAME like 'VALIDATION1_%' ]';

Resources