Set a variable value in stored procedure and use in following query - stored-procedures

How can I set a variable in stored procedure and use it in following query to be executed.
create or replace procedure sp1()
returns table (dealer_id varchar, dealershipgroup_name varchar)
language sql
as
$$
declare
create_query varchar;
res resultset;
MISSING_DEALER NUMBER(38,0) default 0;
begin
MISSING_DEALER := 100;
select_query := 'WITH CTE AS(
SELECT dealer_id,
CASE WHEN dealer_id=:MISSING_DEALER then \'Abc\'
WHEN dealershipgroup IS NULL then \'\'
ELSE dealershipgroup end as dealershipgroup FROM TBL )
select * from CTE';
res:= (execute immediate : select_query);
return table(res);
end;
$$;
call sp1();
Could someone please suggest how can I use MISSING_DEALER in the query. I am currently getting the following error
Uncaught exception of type 'STATEMENT_ERROR' on line 28 at position 9 : SQL compilation error: error line 8 at position 26 Bind variable :MISSING_DEALER not set

You need to concatenate the string parts of your SQL statement with the variable. This is covered in the documentation if you look at the end of the section here

Related

How to write multi line query in snowflake scripting in stored procedure

create or replace procedure create_src_table()
returns table (name varchar, age number(10,0),dob date)
language sql as
$$
declare
create_query varchar;
res resultset;
begin
create_query := `CREATE TEMPORARY TABLE SRC_TEMP_TBL AS SELECT * FROM
(WITH CTE_1 AS (SELECT * FROM "DB"."DW"."USER_TBL" WHERE name='rahul'),
CTE_2 AS (SELECT * FROM CTE_1 WHERE CAST(DOB AS DATE)<2000-05-01)
SELECT name,age,dob FROM CTE_2 limit 10)`;
res := (execute immediate : create_query);
return table(res);
end;
$$;
call create_src_table();
Could someone please help in how to write multiline sql query. I found few answers that indicate using backtick in javascript but not sure how to achieve it in sql.
Multi-statement SQL should be wrapped inside BEGIN ... END block:
EXECUTE IMMEDIATE 'BEGIN
statement1;
statement2;
...
END;';
Sample:

Anyone knows why LPAD function returns an error when it is called during UNLOAD command inside Redshift stored procedure?

I'm trying to call the LPAD function during the UNLOAD command inside a Redshift stored procedure and it keeps returning an error: Amazon Invalid operation: syntax error at or near "9" . Can anyone help me address this error?
The column that LPAD is applied to is VARCHAR data type. Basically, I'm adding leading "0" to records that are less than 9 character long.
If it matters, I'm using Aginity Pro as the query editor while connecting to Redshift. Here is an example stored procedure:
CREATE OR REPLACE PROCEDURE schemaname.sp_example ()
LANGUAGE plpgsql
AS
$$
DECLARE _CurrentDate VARCHAR(10);
_UnloadQuery VARCHAR(65000);
BEGIN
WITH CTE_CurrentDate AS (SELECT TO_CHAR(CAST(GETDATE() AS DATE), 'YYYYMMDD') AS CurrentDateParm)
SELECT CurrentDateParm INTO _CurrentDate FROM CTE_CurrentDate;
_UnloadQuery := '
UNLOAD ('''||
'
SELECT B.column_name
FROM tbl_a a
INNER JOIN tbl_b B
on LPAD(a.column_name,'''||$9||''',''0'') = B.column_name
GROUP BY B.column_name
'
||'''
)
to '''||'s3://address_'||_CurrentDate||'.CSV'||'''
credentials '''||'aws_access_key_id=xxx'||';'||'aws_secret_access_key=xxx'||'''
Header
ALLOWOVERWRITE
delimiter '''||','||'''
addquotes
PARALLEL OFF
';
EXECUTE _UnloadQuery;
END;
$$;

Stored procedure is not getting complied

I am trying to run the below stored procedure in Oracle pl/sql. I am trying to fetch data from join in cursor using table 1 and table 2 and update the output in Table 3, however its giving me compliation error near declare. The queries are working fine.
create or replace PACKAGE BODY PKG_LOAD_BY_ROWID AS
PROCEDURE PRC_LOAD_BY_ROWID AS
DECLARE
N1 NUMBER;
VAR_ROWID_OBJECT VARCHAR2(255);
VAR_PRTY_FK VARCHAR2(255);
V_OUT_ERROR_MSG VARCHAR2(1000);
v_out_return_code number;
CURSOR C1 IS
SELECT PX.ROWID_OBJECT , A.PRTY_FK
FROM TABLE_1 PX
INNER JOIN
TABLE_2 A
ON
substr(PX.PKEY_SRC_OBJECT,8,INSTR(PX.PKEY_SRC_OBJECT,'|')+8)=A.ALT_ID_VAL
WHERE A.ALT_ID_TYP='DUMMY1' AND PX.ROWID_SYSTEM='SRC';
BEGIN
SELECT COUNT(1) INTO N1 FROM TABLE_3 WHERE SRC_SYSTEM='SRC2' AND ROWID_OBJECT IS NULL;
BEGIN
OPEN C1;
FOR i in 1..n1
LOOP
FETCH C1 INTO VAR_ROWID_OBJECT, VAR_PRTY_FK;
UPDATE TABLE3 SET ROWID_OBJECT= VAR_ROWID_OBJECT WHERE
SRC_KEY=VAR_PRTY_FK;
COMMIT;
END LOOP;
CLOSE C1;
v_out_return_code :=0;
DBMS_OUTPUT.put_line('Rowid_object updated successfully for VVA');
EXCEPTION
when others then
out_error_msg := 'Updation Error';
DBMS_OUTPUT.put_line (out_error_msg);
END;
END;
END PKG_LOAD_BY_ROWID;
However, I am getting compilation error:
Error(2,1): PLS-00103: Encountered the symbol "DECLARE" when expecting one of the following: begin function pragma procedure subtype type current cursor delete exists prior external language
Oracle Version:
You don't need Declare keyword for the procedure, it is only for anonymous block. Just remove declare and try it.

Dynamic query in Cursor for %rowtype

I need to create a record type to contain the result set of the above query of
V_SQL VARCHAR2(200) := 'SELECT T1.'||record_id||',T1.'||card_no||',T2.TEST_CARD_NO, T1.'||type_cc||' FROM '|| table_name||' T1
INNER JOIN TEST T2 ON
T2.ID = T1.'||record_id;
So that I can use t1 C_BRNGB_EXTRACT%ROWTYPE (plus another column for t2.col4%TYPE inside l_BRNGB_EXTRACT) inside loop execute statement
CREATE OR REPLACE PROCEDURE "GCCPMAINT"."FUNCTION_CURSOR"(table_name VARCHAR2,record_id VARCHAR2,card_no VARCHAR2,type_cc VARCHAR2)
AS
limit_in NUMBER:=100;
V_SQL VARCHAR2(200) := 'SELECT T1.'||record_id||',T1.'||card_no||',T2.TEST_CARD_NO, T1.'||type_cc||' FROM '|| table_name||' T1
INNER JOIN TEST T2 ON
T2.ID = T1.'||record_id;
TYPE BRNGB_EXTRACT IS REF CURSOR;
C_BRNGB_EXTRACT BRNGB_EXTRACT;
TYPE BRNGB_EXTRACT1 IS TABLE OF C_BRNGB_EXTRACT%ROWTYPE;
l_BRNGB_EXTRACT BRNGB_EXTRACT1;
BEGIN
OPEN C_BRNGB_EXTRACT FOR V_SQL;
LOOP
FETCH C_BRNGB_EXTRACT BULK COLLECT INTO l_BRNGB_EXTRACT LIMIT limit_in;
EXIT WHEN l_BRNGB_EXTRACT.COUNT = 0;
FORALL indx IN 1 .. l_BRNGB_EXTRACT.COUNT
EXECUTE IMMEDIATE 'UPDATE table_name SET CARD_NO=:1 WHERE CARD_NO=:2 AND RECORD_ID=:3' USING l_BRNGB_EXTRACT(indx).test_card_no,l_BRNGB_EXTRACT(indx).CARD_NO,l_BRNGB_EXTRACT(indx).RECORD_ID;
END LOOP;
CLOSE C_BRNGB_EXTRACT;
COMMIT;
END;
For a above stored procedure I'm getting the following error
PLS-00320: the declaration of the type of this expression is
incomplete or malformed PL/SQL: Item ignored PLS-00597: expression
'L_BRNGB_EXTRACT' in the INTO list is of wrong type PL/SQL: SQL
Statement ignored PLS-00487: Invalid reference to variable
'C_BRNGB_EXTRACT%ROWTYPE'
Please help me to solve this.
i got the solution
TYPE BRNGB_EXTRACT IS REF CURSOR;
C_BRNGB_EXTRACT BRNGB_EXTRACT;
-- TYPE BRNGB_EXTRACT1 IS TABLE OF C_BRNGB_EXTRACT%ROWTYPE;
TYPE BRNGB_EXTRACT1 IS RECORD (
record_id varchar(30),
card_no varchar(30),
TEST_CARD_NO varchar(30)
);
type test_rec_arr is table of BRNGB_EXTRACT1 index by pls_integer;
l_BRNGB_EXTRACT test_rec_arr;

Inserting values in to netezza using a stored procedure

I'm working with netezza database and have a requirement to insert a Y flag for stores in California. I wrote the below procedure
CREATE OR REPLACE PROCEDURE MY_NEW_PROCEDURE() RETURNS BOOL
EXECUTE AS OWNER LANGUAGE NZPLSQL AS
BEGIN_PROC
DECLARE
rec RECORD;
BEGIN
FOR rec in SELECT * from test_table
LOOP
if rec.state_code ='CA'
EXECUTE IMMEDIATE 'INSERT INTO test_table (california_stores)' || 'values('y')';
END LOOP;
END;
END_PROC;
when I call the procedure using call MY_NEW_PROCEDURE() I get an error at line EXECUTE IMMEDIATE. I'm not sure what change I need to make here.
Don't know about netezza, but below is the procedure I used to test this (using SQL developer).
Works fine for me, although it would make more sense to update the row to set california_stores to 'Y'rather than insert a new row with california_stores = 'Y' for each calafornia store that you have.....
CREATE OR REPLACE PROCEDURE "MY_NEW_PROCEDURE" as
rec test_table2%rowtype;
BEGIN
FOR rec in (SELECT * from test_table2) LOOP
if rec.state_code = 'CA' then
EXECUTE IMMEDIATE 'INSERT INTO test_table2 (california_stores)' || 'values(''y'')';
end if;
END LOOP;
END;
You didn't post the second error, but it looks to me like your insert statement isn't going to do what you want anyway. If the rec variable contains the attribute state_code and you're inserting a single value to test_table then the record will simply be empty except for a 'Y' in california_stores.
I'm going to guess that you're getting an error now either because of the spacing in the insert statement insert into test_table (california_stores)values('y') or because you didn't terminate the execute statement with a semicolon. The plsql for that line should be
execute immediate 'insert into test_table (california_stores) values (''y'');';

Resources