Serverless task in Snowflake - sql

I am executing below statement for serverless task it's throwing an error
CREATE OR REPLACE TABLE TASK_TABLE_2(TBL_NAME VARCHAR, LAST_INSERTED_DATE TIMESTAMP);
CREATE OR REPLACE TABLE TASK_TABLE_3(TBL_NAME VARCHAR, LAST_INSERTED_DATE TIMESTAMP);
create or replace task DEMO_TASK_2
USER_TASK_MANAGED_INITIAL_WAREHOUSE_SIZE = 'XSMALL'
SCHEDULE ='1 minutes'
as
EXECUTE IMMEDIATE
$$
BEGIN
insert into TASK_TABLE_2 values (2_1,SYSDATE());
insert into TASK_TABLE_2 values (2_2,SYSDATE());
insert into TASK_TABLE_3 values (3_1,SYSDATE());
END
$$
;
Error Message:
Uncaught exception of type 'STATEMENT_ERROR' on line 3 at position 0 : No active warehouse selected in the current session. Select an active warehouse with the 'use warehouse' command.
But the same executing successfully if i use the warehouse in the TASK
CREATE OR REPLACE TABLE TASK_TABLE(TBL_NAME VARCHAR, LAST_INSERTED_DATE TIMESTAMP);
CREATE OR REPLACE TABLE TASK_TABLE_1(TBL_NAME VARCHAR, LAST_INSERTED_DATE TIMESTAMP) ;
create or replace task DEMO_TASK
WAREHOUSE = COMPUTE_WH
SCHEDULE ='1 minutes'
as
EXECUTE IMMEDIATE
$$
BEGIN
insert into TASK_TABLE values (0_1,SYSDATE());
insert into TASK_TABLE values (0_2,SYSDATE());
insert into TASK_TABLE_1 values (1_1,SYSDATE());
END
$$
;

This worked for me, looks like you forgot to add USE Warehouse for creation of task, as creation of task is not metadata based action , so please use "USE WAREHOUSE " sql statement before you execute create task
create or replace task DEMO_TASK_2
USER_TASK_MANAGED_INITIAL_WAREHOUSE_SIZE = 'XSMALL'
SCHEDULE ='1 minutes'
as
EXECUTE IMMEDIATE
$$
BEGIN
insert into TASK_TABLE_2 values (2_1,SYSDATE());
insert into TASK_TABLE_2 values (2_2,SYSDATE());
insert into TASK_TABLE_3 values (3_1,SYSDATE());
END
$$
;

The case is reproducible and my hypothesis is serverless task does play well with standalone Snowflake Scripting BEGIN END block.
Initial setup(tested using Snowsight UI):
CREATE OR REPLACE TABLE TASK_TABLE_2(TBL_NAME VARCHAR, LAST_INSERTED_DATE TIMESTAMP);
CREATE OR REPLACE TABLE TASK_TABLE_3(TBL_NAME VARCHAR, LAST_INSERTED_DATE TIMESTAMP);
SELECT CURRENT_VERSION();
-- 7.5.2
Task test:
EXECUTE TASK DEMO_TASK_2 ;
SELECT *
FROM TABLE(information_schema.task_history())
ORDER BY scheduled_time DESC;
Use case 1:
CREATE OR REPLACE TASK DEMO_TASK_2
USER_TASK_MANAGED_INITIAL_WAREHOUSE_SIZE = 'XSMALL'
SCHEDULE ='1 minutes'
AS
EXECUTE IMMEDIATE
$$
BEGIN
insert into TASK_TABLE_2 values ('2_1',SYSDATE());
insert into TASK_TABLE_2 values ('2_2',SYSDATE());
insert into TASK_TABLE_3 values ('3_1',SYSDATE());
END
$$;
-- Task DEMO_TASK_2 successfully created.
Output:
Uncaught exception of type 'STATEMENT_ERROR' on line 2 at position 0 : No active warehouse selected in the current session. Select an active warehouse with the 'use warehouse' command.
Use case 2
No EXECUTE IMMEDIATE, only Snowflake Scripting block
CREATE OR REPLACE TASK DEMO_TASK_2
USER_TASK_MANAGED_INITIAL_WAREHOUSE_SIZE = 'XSMALL'
SCHEDULE ='1 minutes'
AS
BEGIN
insert into TASK_TABLE_2 values ('2_1',SYSDATE());
insert into TASK_TABLE_2 values ('2_2',SYSDATE());
insert into TASK_TABLE_3 values ('3_1',SYSDATE());
END;
-- Task DEMO_TASK_2 successfully created.
Output:
Uncaught exception of type 'STATEMENT_ERROR' on line 2 at position 0 : No active warehouse selected in the current session. Select an active warehouse with the 'use warehouse' command.
Use case 3:
EXECUTE IMMEDIATE with BEGIN END block including only single statement:
CREATE OR REPLACE TASK DEMO_TASK_2
USER_TASK_MANAGED_INITIAL_WAREHOUSE_SIZE = 'XSMALL'
SCHEDULE ='1 minutes'
AS
EXECUTE IMMEDIATE
$$
BEGIN
insert into TASK_TABLE_2 values ('2_1',SYSDATE());
END;
$$;
-- Task DEMO_TASK_2 successfully created.
Uncaught exception of type 'STATEMENT_ERROR' on line 3 at position 0 : No active warehouse selected in the current session. Select an active warehouse with the 'use warehouse' command.
Use case 4:
EXECUTE IMMEDIATE no BEGIN END and single statement:
CREATE OR REPLACE TASK DEMO_TASK_2
USER_TASK_MANAGED_INITIAL_WAREHOUSE_SIZE = 'XSMALL'
SCHEDULE ='1 minutes'
AS
EXECUTE IMMEDIATE
$$
insert into TASK_TABLE_2 values ('2_1',SYSDATE());
$$;
-- Task DEMO_TASK_2 successfully created.
Output:
SUCCEEDED
Use case 5:
BEGIN END block with single statement:
CREATE OR REPLACE TASK DEMO_TASK_2
USER_TASK_MANAGED_INITIAL_WAREHOUSE_SIZE = 'XSMALL'
SCHEDULE ='1 minutes'
AS
BEGIN
insert into TASK_TABLE_2 values ('2_1',SYSDATE());
END;
-- Task DEMO_TASK_2 successfully created.
Output:
Uncaught exception of type 'STATEMENT_ERROR' on line 2 at position 0 : No active warehouse selected in the current session. Select an active warehouse with the 'use warehouse' command.
Use case 6:
Single statement:
CREATE OR REPLACE TASK DEMO_TASK_2
USER_TASK_MANAGED_INITIAL_WAREHOUSE_SIZE = 'XSMALL'
SCHEDULE ='1 minutes'
AS
insert into TASK_TABLE_2 values ('2_1',SYSDATE());
-- Task DEMO_TASK_2 successfully created.
Output:
SUCCEEDED
Outcome:
Task creation - succeeded in all 6 cases
Task run - succeeded only in case 4,6 (no BEGIN END block)
It should be reported to Snowflake Support.

Related

How to insert data into table even if trigger fails?

Oracle 11.1
I have custom logging table where I insert data:
CREATE TABLE log_table
(
message VARCHAR2(255),
created_by VARCHAR2(40) NOT NULL,
created_at DATE NOT NULL,
);
I have a trigger that runs on a specific table which does some checkings. My problem is: when the trigger fails, I want to be able to log some data into the log_table.
Trigger:
CREATE OR REPLACE TRIGGER my_trigger
FOR INSERT OR UPDATE OF column
ON my_table
COMPOUND TRIGGER
BEFORE STATEMENT IS
BEGIN
// code
END BEFORE STATEMENT;
BEFORE EACH ROW IS
BEGIN
IF (/*condition for failing*/) THEN
EXECUTE IMMEDIATE 'INSERT INTO mesaj_ama VALUES (:my_message, :my_user, :my_data)'
USING 'custom error message', SYS.LOGIN_USER, SYSDATE;
RAISE_APPLICATION_ERROR(-20001, 'some error');
END IF;
END BEFORE EACH ROW;
END my_trigger;
/
The following code doesn't work. I tried to use EXECUTE IMMEDIATE maybe to force it, but didn't work. I know that in case of an error, there is automatically a table rollback (which means that the INSERT command is cancelled), but I need a way to do this. Any help?
The concept you're looking for is an Autonomous Trasnaction, eg
CREATE OR REPLACE TRIGGER log_sal
BEFORE UPDATE OF salary ON emp FOR EACH ROW
DECLARE
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
INSERT INTO log (
log_id,
up_date,
new_sal,
old_sal
)
VALUES (
:old.employee_id,
SYSDATE,
:new.salary,
:old.salary
);
COMMIT;
END;
Yes, PRAGMA AUTONOMOUS_TRANSACTION seems to be the answer. Here is the working code:
Defined a procedure for logging:
CREATE OR REPLACE PROCEDURE log_error(p_error log_table.message % TYPE) AS
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
INSERT INTO log_table
VALUES (p_error, SYS.LOGIN_USER, SYSDATE);
COMMIT;
END;
and the trigger which calls the procedure:
CREATE OR REPLACE TRIGGER my_trigger
FOR INSERT OR UPDATE OF column
ON my_table
COMPOUND TRIGGER
BEFORE STATEMENT IS
BEGIN
// code
END BEFORE STATEMENT;
BEFORE EACH ROW IS
BEGIN
IF (/*condition for failing*/) THEN
log_error('custom error message');
RAISE_APPLICATION_ERROR(-20001, 'custom error message');
END IF;
END BEFORE EACH ROW;
END my_trigger;
/

Creating database table in PL/SQL procedure

I am trying to create table with procedure CREATE_TABLE and then insert the information into the created table with procedure PRINT_INFO but I am getting an exception:
Errors: PROCEDURE PRINT_INFO Line/Col: 4/3 PL/SQL: SQL Statement
ignored Line/Col: 4/15 PL/SQL: ORA-00942: table or view does not exist
Errors: PROCEDURE CREATE_TABLE Line/Col: 5/3 PLS-00103: Encountered
the symbol "CREATE" when expecting one of the following:
( begin case declare exit for goto if loop mod null pragma raise
return select update while with << continue close current
delete fetch lock insert open rollback savepoint set sql execute
commit forall merge pipe purge json_exists json_value json_query
json_object json_array
And here is my code example:
CREATE OR REPLACE PROCEDURE PRINT_INFO
IS
BEGIN
INSERT INTO TABLE_T (TABLE_ID, MESSAGE) VALUES (1, 'Hello World!');
END PRINT_INFO;
/
CREATE OR REPLACE PROCEDURE CREATE_TABLE
IS
BEGIN
CREATE TABLE TABLE_T(
TABLE_ID NUMBER NOT NULL,
MESSAGE VARCHAR2(25),
PRIMARY KEY(TABLE_ID)
);
PRINT_INFO;
END CREATE_TABLE;
/
EXEC CREATE_TABLE;
Where could be the problem? How can I get rid of an exception?
Both procedures have to use dynamic SQL:
print_info because it inserts into a table which - at compilation time - doesn't exist yet
create_table because it runs DDL and - in order to do that - you need to use dynamic SQL
Therefore:
SQL> CREATE OR REPLACE PROCEDURE PRINT_INFO
2 IS
3 BEGIN
4 execute immediate q'[INSERT INTO TABLE_T (TABLE_ID, MESSAGE) VALUES (1, 'Hello World!')]';
5 END PRINT_INFO;
6 /
Procedure created.
SQL> CREATE OR REPLACE PROCEDURE CREATE_TABLE
2 IS
3 BEGIN
4 execute immediate 'CREATE TABLE TABLE_T(' ||
5 'TABLE_ID NUMBER NOT NULL, ' ||
6 ' MESSAGE VARCHAR2(25), ' ||
7 ' PRIMARY KEY(TABLE_ID) ' ||
8 ')';
9
10 PRINT_INFO;
11 END CREATE_TABLE;
12 /
Procedure created.
SQL> EXEC CREATE_TABLE;
PL/SQL procedure successfully completed.
SQL> SELECT * FROM table_t;
TABLE_ID MESSAGE
---------- -------------------------
1 Hello World!
SQL>
You have to declare a string and assign your ddl to that variable then use
execute immediate your_variable ;

PL PQL doesn't get executed properly

I have to insert almost 40 000 rows to a table and every time I try to execute it in SQL developer, I couldn't find any rows in the table it seems like it didn't executed the begin block at all, because i put a msg to be printed in the output and there is nothing after the execution, I have tried to execute the block with only a few insertion statements and it works,
why SQL developer can't handle a lot of insertion statement in PLSQL block?
bellow is my script:
set serveroutput on
set linesize 200
set timing on
whenever sqlerror exit failure rollback;
whenever oserror exit failure rollback;
ALTER SESSION SET current_schema = carp;
ALTER SESSION SET nls_length_semantics = char;
DECLARE
v_rows_count VARCHAR2(10 CHAR);
PROCEDURE trace (p_message IN VARCHAR2)
IS
BEGIN
DBMS_OUTPUT.put_line (TO_CHAR (SYSDATE, 'YYYYMMDD HH24:MI:SS') || ' - INFO - ' || p_message);
END trace;
BEGIN
dbms_output.ENABLE(1000000);
TRACE ('=========== Exécution du script: START ===========');
Insert into my_table (PK_SEQ,CODE) values (1260389,'00AI');
Insert into my_table (PK_SEQ,CODE) values (1321244,'00AI');
select COUNT(*) into v_rows_count FROM carp.param_site_groupe_site;
dbms_output.put_line('Nombre de lignes insérées: ' || v_rows_count);
TRACE (q'[=========== Exécution du script: FIN ===========]');
COMMIT;
END;
/
exit;
please note that there is more than 40 000 insert statements inside the begin block not two as shown above
I reduce the script size just for readebility porpuse

sql insert procedure: insert values into table and control if value is existing in another table

I have little problem. I am trying to insert value into table. This is working. But I would like to control if value id_trainer is existing in another table. I want this -> execute insertClub(1, 5, 'someName'); -> and if id_trainer 5 not exists in table Trainer, procedure gives me message about this. (I tried to translate it into eng. lng., so you can find some gramm. mistakes)
create or replace procedure insertClub
(id_club in number, id_trainer in number, clubName in varchar2)
is
begin
declare counter number;
select count(*) into counter from trianer tr where tr.id_trainer = id_trainer;
if counter = 0 then
DBMS_OUTPUT.PUT_LINE('Trainer with this ID not exists');
end if;
insert into club values(id_club, id_trainer, clubName);
exception
when dup_val_on_index then
DBMS_OUTPUT.PUT_LINE('Dup ID');
end;
/
There is some error in the procedure. Please run below code to create procedure:
create or replace procedure insertClub
(id_club in number, id_trainer in number, clubName in varchar2)
is
counter number;
begin
select count(*) into counter from trianer tr where tr.id_trainer = id_trainer;
if counter = 0 then
DBMS_OUTPUT.PUT_LINE('Trainer with this ID not exists');
end if;
insert into club values(id_club, id_trainer, clubName);
exception
when dup_val_on_index then
DBMS_OUTPUT.PUT_LINE('Dup ID');
end;
/

INSERT after EXECUTE IMMEDIATE in oracle [duplicate]

I'm trying to create a table and then insert some values in it within the same procedure in pl/sql. I tried to run the following query without success:
create or replace Procedure insertval8(id_no in number,e_name in char)
is
begin
execute immediate 'create table edu2(id number(20), name char(12))';
insert into edu2 values(&id_no,&e_name);
end;
displays
LINE/COL ERROR
-------- -----------------------------------------------------------------
5/1 PL/SQL: SQL Statement ignored
5/13 PL/SQL: ORA-00942: table or view does not exists
The error persists until I remove the insert code.
The procedure cannot be compiled because the table is not present at compile time.
Wrap the insert in execute immediate also, or use a global temporary table (generaly the preferred solution for temporary data).
create or replace procedure insertval8 (id in number,
name in char )
is
begin
execute immediate 'create table edu2(id number(20), name char(12))';
execute immediate 'insert into edu2(id, name) values (:1, :2)'
using id, name;
end;