Using Variables in Nested query for Execute Immediate - sql

This might be a simple query for most of you.
I would like to use a variable in nested query while writing an execute immediate, but somehow it throws an error everytime on the variable in nested query.
create or replace PROCEDURE p_decrement_id(
in_table VARCHAR2,
in_seg_nme VARCHAR2)
AS
version VARCHAR2(5) := 'v1.0';
BEGIN
EXECUTE IMMEDIATE 'UPDATE '|| in_table || '
SET X_VERSION_ID = X_VERSION_ID - 1
where DATE_1 = (SELECT DATE_2 FROM CYCLE_DATES
WHERE SEG_NME = ' ||in_seg_nme||')';
COMMIT;
END p_decrement_id;
for execution I use:
set serveroutput on
call p_decrement_id('TEST_DECREMENT', 'TEST');
Also, I need to put a constant value within the query
i.e.
SELECT DATE_2 FROM CYCLE_DATES
WHERE SEG_NME = ' ||in_seg_nme||'
and indicator = 'Y'
Please guide.
Thank you all in advance

It's better to use USING to bind params to your query
EXECUTE IMMEDIATE 'UPDATE '|| in_table || '
SET X_VERSION_ID = X_VERSION_ID - 1
where DATE_1 = (SELECT DATE_2 FROM CYCLE_DATES
WHERE SEG_NME = :1 and indicator = ''Y'')' using in_seg_nme;
Without USING you may try this (as it's VARCHAR2 you need '):
EXECUTE IMMEDIATE 'UPDATE '|| in_table || '
SET X_VERSION_ID = X_VERSION_ID - 1
where DATE_1 = (SELECT DATE_2 FROM CYCLE_DATES
WHERE SEG_NME = ''' ||in_seg_nme||''' and indicator = ''Y'')';
(Two consequent apostrophies is an escape sequence for apostrophe)

Related

Update Query not working inside postgresql function but it works fine outside function

I am creating function in postgresql to update table. when I ran single function it works fine but I use same query inside function it wont works.
update house1 SET calendar=
'H'||' '||house_num::text||' '||left(to_char(sdate, 'Mon'),2) ||' to ' || to_char(sdate, 'DD') ||to_char(rdate, 'Mon-DD')
where id=1
Inside function I wrote following query
begin
execute
'UPDATE house1 SET calendar = '
||quote_nullable( 'H')||' '||house_num||' '||left(to_char(sdate, 'Mon'),2) ||' to ' || to_char(sdate, 'DD') ||to_char(rdate, 'Mon-DD')
|| ' WHERE' || 'stage'
'>=' || quote_nullable(0) ;
END
It generates following error
ERROR: column "house_num" does not exist.
Please help me
Why do you use the execute statement in function?
You can use update statement directly in function (When using the execute statement if you need to build dynamic query)
create or replace function function_name()
returns void
language plpgsql
as
$$
begin
update house1 SET calendar=
'H'||' '||house_num::text||' '||left(to_char(sdate, 'Mon'),2) ||' to ' || to_char(sdate, 'DD') ||to_char(rdate, 'Mon-DD')
where stage >= 0;
end;
$$;
select function_name();

Cursor in Oracle - after passing parameters, select does not filter result rows

I am facing for me strange issue with following parametrical cursor.
I have defined cursor in this way:
CURSOR cur_action ( product_code VARCHAR2(100) , action_master_list VARCHAR2(100))
IS
SELECT
act.ACTION_DETAIL_KEY,
act.ACTION_MASTER_KEY,
act.PRODUCT_CODE,
act.REF_ACTION_DETAIL_KEY
FROM XMLTABLE(action_master_list) x
JOIN ETDW.MFE_AR_ACTION_DETAILS act ON TO_NUMBER(x.COLUMN_VALUE) = act.ACTION_MASTER_KEY
WHERE 1=1
AND act.LAST_FLAG = 'Y'
AND act.PRODUCT_CODE = product_code;
Then I am using it in following way:
OPEN cur_action ( iFromProductCode , iActionMasterKeyList);
LOOP
FETCH cur_action BULK COLLECT INTO vActionDetailKey, vActionMasterKey, vProductCode, vRefActionDetailKey LIMIT 100;
FOR j IN 1..cur_action%ROWCOUNT
LOOP
dbms_output.put_line('vActionDetailKey: ' || vActionDetailKey (j) ||' vActionMasterKey: '|| vActionMasterKey (j) || ' vProductCode: ' || vProductCode (j));
END LOOP;
END LOOP;
Result seems to be unfilterd. It doesnt return 3 rows as expected result (this result is returned in with cusor query, when i run in outside procedure/pl block), but it returns all rows for actions in list. So it seems, that WHERE condition "act.PRODUCT_CODE = product_code" was not applied. Why?
Thank you
Why? Because you named parameter the same as column, so Oracle reads it as if it was where 1 = 1, i.e. no filtering at all.
Rename parameters to e.g.
CURSOR cur_action ( par_product_code V
----
this
and, later,
AND act.PRODUCT_CODE = par_product_code;
----
this

Proc oracle issue - call executed but no insertion ( ORACLE / PLSQL )

Im trying to make a procedure in oracle with PL/SQL. This proc has to call a function with a value return and then update a colown with this value. My proc is executing normaly but the insertion to try the proc are not working. Im a bit lost.
The proc :
PROCEDURE depot_enrichment(babas number) IS
-- Curseur
CURSOR V_CURS_CDIS_CTC IS SELECT DISTINCT CD_REGATE,
OPT_SITE_DEPOT,
TYP_PARUTION_DECLA,
NUM_PUBLICATION_DECLA,
CD_POSTAL,
ID_LIB_PREP
FROM DEPOT_IMPORT
WHERE OPT_SITE_DEPOT = 81001210 OR OPT_SITE_DEPOT = 81001211;
-- Variables proc
p_opt_site varchar2(40); -- DepotCDIS/DepotCTC
-- Variables parameters function
v_CodeSiteDepot VARCHAR2(40); ----- 531980
v_OptionSiteDepot VARCHAR2(40); ---- 81001210/81001211
v_TypeParution VARCHAR2(40); ---- N1, N2, N3 ..........
v_NoPublication VARCHAR2(40);---- 1222K82523
v_codePostal VARCHAR2(40); ----- 55000
v_NiveauPrepa VARCHAR2(40); ---- 50001,50002,5003
-- Libelle parameters function
v_LibOptionSiteDepot VARCHAR2(40); ---- DepotCDIS/DepotCTC
v_LibTypeParution VARCHAR2(40); ---- NUM , FCS ..........
v_LibNiveauPrepa VARCHAR2(40); ---- ATTF, LATD, LDCP, LDQL ou PEM
BEGIN
-----------------------------------------------------------------------------------------------------
-- SUB-PROC OPT SIT DEPOT ENRICHIMENT - ENR4 :détermination de OptionSiteDepot pour les produits Presse
-- Enrichment of the opt_site_depot - JIRA : 1003
-----------------------------------------------------------------------------------------------------
-- option DepotCDIS / CTC
OPEN V_CURS_CDIS_CTC;
LOOP
fetch V_CURS_CDIS_CTC into v_CodeSiteDepot,v_OptionSiteDepot,v_TypeParution,v_NoPublication,v_codePostal,v_NiveauPrepa;
EXIT WHEN V_CURS_CDIS_CTC%notfound;
Insert into babas values ('Parametres : ' || v_CodeSiteDepot || ' / ' || v_OptionSiteDepot || ' / ' || v_TypeParution || ' / ' || v_NoPublication || ' / ' || v_codePostal || ' / ' || v_NiveauPrepa);
-- GET LIBELLE FROM PARAMETERS VARIABLES
SELECT LIB.LIB_LIBELLE INTO v_LibOptionSiteDepot FROM LIBELLE LIB WHERE typ_libelle = 'OSD' and id_libelle = v_CodeSiteDepot;
SELECT TYP.LIB_PARUTION INTO v_LibTypeParution FROM TYPE_PARUTION TYP WHERE id_type_parution = v_TypeParution;
SELECT LIB.VAL_LIBELLE INTO v_LibNiveauPrepa FROM LIBELLE LIB WHERE typ_libelle = 'PEC' and id_libelle = v_NiveauPrepa;
Insert into babas values ('Parametres libelles: ' || v_CodeSiteDepot || ' / ' || v_LibOptionSiteDepot || ' / ' || v_LibTypeParution || ' / ' || v_NoPublication || ' / ' || v_codePostal || ' / ' || v_LibNiveauPrepa);
-- CALL FUNCTION
p_opt_site := return_option_CDIS_CTC(v_CodeSiteDepot,v_LibOptionSiteDepot,v_LibTypeParution,v_NoPublication,v_codePostal,v_LibNiveauPrepa);
Insert into babas values ('option site dépot : ' || p_opt_site);
-- UPDATE ROWS
UPDATE DEPOT_IMPORT SET OPT_SITE_DEPOT = p_opt_site;
END LOOP;
CLOSE V_CURS_CDIS_CTC;
END depot_enrichment;
When i call the proc :
what is inserted in babas table :
I've the impression the modification code into libelle ( the 3 select ) is not working, i try the query alone and it returns me the right value. I dont understand, if you have any documentions or advises, will be really cool :)
Commit is necessary to be placed at the end of the procedure to reflect the changes.
....
....
UPDATE DEPOT_IMPORT SET OPT_SITE_DEPOT = p_opt_site;
END LOOP;
COMMIT; -- this is needed here
CLOSE V_CURS_CDIS_CTC;
There are 3 insert into babas statements within the loop, but - according to output you get, only the first one:
Insert into babas values ('Parametres : ' ...
does its job. Where are other two?
When calling the procedure, you specified owner name:
call sagapec_import.depot_enrichment(0);
--------------
this
Is the babas table owned by that user? Are you connected as sagapec_import? Because, maybe you're executing procedure in one schema and check the result in another.
Finally, this:
UPDATE DEPOT_IMPORT SET OPT_SITE_DEPOT = p_opt_site;
doesn't contain WHERE clause which means that you'll every time update all rows in that table. Is that correct?

Not properly closed sql command

I have this code:
def_where:=def_where||' TO_CHAR(date_of_input,''MM'') like '''||'to_char(date_of_input,''MM'')=nvl(:DSP_month,to_char(date_of_input,''MM''))'||'%' ||'to_char(date_of_input,''RRRR'')=nvl(:DSP_year,to_char(date_of_input,''RRRR''))'||'%''';
and i m getting error sql command not properly ended.
def_where suggest, that this is part of dynamically built query, condition of where clause. But produced string makes no sense, it should be something like:
declare
def_where varchar2(32767) := '';
begin
def_where := def_where
|| ' to_char(date_of_input, ''MM'') '
|| ' = nvl(:DSP_month, to_char(date_of_input, ''MM'')) and'
|| ' to_char(date_of_input, ''RRRR'') '
|| ' = nvl(:DSP_year, to_char(date_of_input, ''RRRR''))';
dbms_output.put_line(def_where);
end;
Look what you got from dbms_output, correct this syntax if needed. You could also rewrite your string to get this:
(extract(month from date_of_input) = :DSP_month or :DSP_month is null) and
(extract(year from date_of_input) = :DSP_year or :DSP_year is null)

SQL stmt concatenate(sp*)

I’m dong some SQL work this week and I normally write Java.
I need to add some if's into my SQL like so, but don’t want to do any string concatenation.
This should be an easy one: I just don’t know the SQL syntax
I want to make all those "AND" statements "if" conditions for params I’m passing in
Would I have to do something like this:
IF p_sac IS NOT NULL
THEN
stmt := stmt || ' AND nsns.sac = ''' || p_sac || '''';
END IF;
IF p_value1 IS NOT NULL
THEN
stmt := stmt || ' AND UPPER(value1s.value1) LIKE ''' || UPPER(p_value1) || ''' ';
END IF;
Or is there an alternative to this above?
Basically I've got this:
FUNCTION summarize_item_search_data (p_obj_code IN VARCHAR2, p_value1 IN VARCHAR2,
p_sac IN NUMBER, p_job_type_id IN NUMBER,
p_value4 IN NUMBER)
RETURN sys_refcurvalue2
IS
result_cur sys_refcurvalue2;
BEGIN
OPEN result_cur FOR
SELECT DISTINCT jp.id, jp.row_top.mwslin AS mwslin, jp.obj_code, jp.jobload_year, jp.row_top.fiscal_year AS fiscal_year,
nsns.sac, value1s.value1, nsns.nsn,
DECODE( jp.row_top.nsn_id, NULL, jp.row_top.nomenclature ,nsns.nomenclature) AS nomenclature, jp.row_top.value4 AS value4
FROM scabs sch, jobs JP, master_nsn nsns, master_value1 value1s, TABLE(value1s.group_id) (+) ntab,
groups pgds
WHERE jp.row_top.nsn_id = nsns.id(+) AND nsns.value1_id = value1s.id(+)
-- stmt := stmt || ' AND ''' || p_year || ''' = ntab.fiscal_year(+)';
AND ntab.group_id = pgds.id(+)
AND nsns.sac = p_sac
AND UPPER(value1s.value1) LIKE UPPER(p_value1)
AND UPPER(jp.obj_code) = UPPER(p_obj_code)
AND jp.row_top.value4 <= p_value4
AND jp.row_top.job_type_id =p_job_type_id
RETURN result_cur;
END summarize_item_search_data;
Just put it all into your WHERE clause as conditions:
WHERE
(p_sac IS NULL OR nsns.sac = p_sac) AND
....
If performance suffers greatly then you might want to look into using dynamic SQL, but I would start with the approach above.