I do have a situation where a programmer who has developed a stored procedure is absent and doesn't work anymore, so I have to make a little bit of update to the code. I should add 2 more variables in to the code and I know the place, but I don't know how to put it.. Could you please describe the following code, what it does in terms of sql? Cause I know what for this code stand inside the programm..
RAISE NOTICE 'STAT CARD: formid=%',formid;
DROP TABLE IF EXISTS tbl_aggregation;
-- execute
sql_ := 'CREATE TEMPORARY TABLE tbl_aggregation as ' --select programstageinstanceid,'|| dynamic_columns ||' from patientdatavalue'
||'
select OrgUnitID
, max(dateperiod) as dateperiod
, programstageinstanceid
, max("[DE:202062.202063.575]"::integer) as "[DE:202062.202063.575]"
, max(
(case when position(''-'' in "[DE:202062.202063.202095]")>0 then substring("[DE:202062.202063.202095]" from 0 for position(''-'' in "[DE:202062.202063.202095]"))
else "[DE:202062.202063.202095]" end)
) as "[DE:202062.202063.202095]"
, sum("[DE:202062.202063.202078]"::integer) as "[DE:202062.202063.202078]"
, max("[DE:202062.202063.202076]") as "[DE:202062.202063.202076]"
from
(
select psi.organisationunitid as OrgUnitID
, ou.name as OrgName, pdv.timestamp as DatePeriod
, pdv.programstageinstanceid
, pdv.dataelementid
, pdv.value,'
|| dynamic_columns ||'
from patientdatavalue pdv inner join programstageinstance psi
on pdv.programstageinstanceid = psi.programstageinstanceid
-- left join organisationunit ou
inner join tbl_org_list ou
on psi.organisationunitid = ou.organisationunitid
where psi.completed=''t'' and
psi.duedate >= '''||period_from ||''' and
psi.duedate <= '''||period_to ||'''
)as aggregation_
'||cCondition||'
group by programstageinstanceid, OrgUnitID
';
In this code there are hard-coded "variables" as [DE:202062.202063.575], and [DE:202062.202063.202078] and etc.. I do have 2 more different [DE:xxx,xxx,xx] which I should add here.
Because whenever I run this storing procedure it doesn't work and gives the error that those new [DE:xxx,xxx,xx] doesn't exist.. So I should make them exist in the code, but where to put them? TO do it I have to understand the sql syntax and what it does, and unfortunately I'm noob in sql.
Related
It's the second question I'm asking for the same issue, so I'll try to be more specific and brief as I can.
In my pl/sql script, i try to insert into a table some records from lots of different tables. I achieve that, except for a field that comes from a JOIN of 2 tables.
The INSERT statement is placed into the following loop:
FOR FST_DEMAND_rec IN (
SELECT *
FROM A
WHERE FK_DEPOSIT_ACCOACC = DEPOSIT_ACC_rec.ACCOUNT_NUMBER
AND TRX_DATE BETWEEN '01-JAN-2018' AND '31-DEC-2018'
ORDER BY TRANS_SER_NUM , ENTRY_SER_NUM ASC)
LOOP
This loop is placed into the following cursor loop :
FOR T IN MOF_CURSOR LOOP
So the INSERT statement, which actually lies in 2 loops, is the following :
INSERT INTO MOF_OUT
VALUES(
T.MOF_REQUEST_ID,
LOC_SERIAL_NUM,
'2B',
CAST(FST_DEMAND_rec.TRX_UNIT || TO_CHAR(FST_DEMAND_rec.TRX_DATE,'YYYYMMDD') || FST_DEMAND_rec.TRX_USR || FST_DEMAND_rec.TRX_SN AS CHAR(50) ),
TO_CHAR(FST_DEMAND_rec.TRX_DATE,'YYYY-MM-DD') ,
CAST(FST_DEMAND_rec.TRX_UNIT AS CHAR(4) ) ,
UNIT_rec.UNIT_NAME ,
CAST(FST_DEMAND_rec.ID_TRANSACT AS CHAR(6) ),
PRFT_TRANS_rec.DESCRIPTION,
-- 'MY PROBLEMATIC FIELD'
TO_CHAR(FST_DEMAND_rec.TIMESTAMP,'hh24miss'),
FST_DEMAND_rec.ENTRY_AMOUNT,
LOC_DC_FLAG,
LOC_PROGR_BALANCE,
LOC_PROGR_BAL_IND
) ;
This INSERT statement works fine, but I don't know how to fill a record which comes from the following SELECT statement with the JOIN clause:
SELECT A.ENTRY_COMMENTS || ' ' || B.DESCRIPTION
FROM FST_DEMAND_EXTRAIT A INNER JOIN JUSTIFIC B ON A.ID_JUSTIFIC = B.ID_JUSTIFIC
For example, the PRFT_TRANS_rec variable that I use in the INSERT, it's declared as PRFT_TRANSACTION%ROWTYPE; and I have the following SELECT statement for it which is within these 2 loops :
SELECT *
INTO PRFT_TRANS_rec
FROM PRFT_TRANSACTION PRFT_TRANS
WHERE PRFT_TRANS.ID_TRANSACT = FST_DEMAND_rec.ID_TRANSACT;
I'm trying to insert value into my temporary table with the code below.
And I got this error
SAP Hana Database Error: cannot
use parameter variable: DOCENTRY: line 8 col 35 (at pos 127) 2 0
I don't know what is wrong,
Please give some advise
thanks
This is the code:
CREATE PROCEDURE REP_PROC11( in docentry nvarchar(2))
AS
totalval DECIMAL (19,6);
BEGIN
CREATE local TEMPORARY TABLE #TempItem AS (
select
'FGA000001' as "ItemCode",
'2IN' as "WhsCode",
ifnull(
(
select
"U_IM1_GR"
from "#OFNC" where "DocEntry" = :docentry
),0) as "Qty",
'11080302' as "Account",
'S02' as "ProfitCode",
'IN-PN' as "ProfitCode2"
from DUMMY
union all
select
'FGA000002' as "ItemCode",
'2IN' as "WhsCode",
ifnull(
(
select
U_IM2_GR
from "#OFNC" where "DocEntry" = :docentry
),0) as "Qty",
'11080302' as "Account",
'S02' as "ProfitCode",
'IN-FN' as "ProfitCode2" from dummy);
SELECT X.*, (X."Qty"*:totalval)/Y."TotalQty" as "Val", :totalval as "TotalVal"
FROM #TempItem X
LEFT JOIN (SELECT SUM(X1."Qty") as "TotalQty" FROM #TempItem X1) Y ON 1 = 1
WHERE X."Qty" > 0;
drop TABLE #TempItem;
end
That’s a limitation of the SQL in your DDL code - the CREATE TEMPORARY TABLE bit.
Given your code so far, you don’t need to use a temp. table but could yield the same result (with less resource usage) by using table variables.
I am at a complete loss as to where my issue is. Earlier on I wrote a procedure that compiled fine, however now I notice that if I take the exact code (even copy/paste from the procedure itself), and try to run it again, SQL Developer essentially freezes and it never compiles.
The SQL itself is certainly not the cleanest, and I am aware that I've made it a little more complex than a better programmer would, however if it compiled earlier it should compile again, no? Below is the P/L SQL in case that may help...
create or replace PROCEDURE insert_comments AS
v_blob BLOB; v_record number;
BEGIN
SELECT blob_content INTO v_blob from xlsx_files;
for x in
(select id into v_record from
(SELECT to_number(id) id, name FROM
(WITH xlsx AS
(SELECT
ROW_NR,
COL_NR,
CASE CELL_TYPE
WHEN 'S'
THEN STRING_VAL
WHEN 'N'
THEN TO_CLOB(NUMBER_VAL)
WHEN 'D'
THEN TO_CLOB(TO_CHAR(DATE_VAL, 'DD-MON-YYYY'))
ELSE
TO_CLOB(FORMULA)
END CELL_VAL
FROM
(SELECT * FROM
TABLE(as_read_xlsx_clob.read(v_blob ))
--as_read_xlsx_clob is a function from the As_read_XLSX_CLOB package
)
)
/*The below statement works as a roundabout way of pivoting
the table. Since the data in the file may contain CLOBs, you
can't use the PIVOT function since CLOBs do not support
aggregation. I have commented out the original SQL that used
PIVOT*/
SELECT id_table.id, name_table.name FROM
(SELECT row_nr, cell_val id FROM
(SELECT * FROM xlsx WHERE row_nr > 1) id_table
where id_table.col_nr=1
) id_table
inner join
(SELECT row_nr, cell_val name FROM
(SELECT *
FROM xlsx
--PIVOT (MAX(TO_CHAR(CELL_VAL))
FOR COL_NR IN (1 AS ROW_WID,2 AS NAME)
) ad
WHERE row_nr >1
) name_table
where name_table.col_nr = 2
) name_table
ON id_table.row_nr = name_table.row_nr
)
)
)
loop
v_record := x.id;
INSERT INTO comment_test(id, name)
(SELECT to_number(id) id, name
FROM
(WITH xlsx AS
(SELECT
ROW_NR,
COL_NR,
CASE CELL_TYPE
WHEN 'S'
THEN STRING_VAL
WHEN 'N'
THEN TO_CLOB(NUMBER_VAL)
WHEN 'D'
THEN TO_CLOB(TO_CHAR(DATE_VAL, 'DD-MON-YYYY'))
ELSE TO_CLOB(FORMULA)
END CELL_VAL
FROM
(SELECT * FROM
TABLE(as_read_xlsx_clob.read(v_blob ))
--as_read_xlsx_clob is a function from the As_read_XLSX_CLOB package
)
)
/*The below statement works as a roundabout way of
pivoting the table. Since the data in the file may
contain CLOBs, you can't use the PIVOT function since
CLOBs do not support aggregation. I have commented out
the original SQL that used PIVOT*/
SELECT id_table.id, name_table.name FROM
(SELECT row_nr, cell_val id FROM
(SELECT * FROM xlsx WHERE row_nr > 1) id_table
where id_table.col_nr=1
) id_table
inner join
(SELECT row_nr, cell_val name FROM
(SELECT *
xlsx
--PIVOT (MAX(TO_CHAR(CELL_VAL))
FOR COL_NR IN (1 AS ROW_WID,2 AS NAME)
) ad
WHERE row_nr >1
) name_table
where name_table.col_nr = 2
) name_table
ON id_table.row_nr = name_table.row_nr)
where to_number(id) = v_record
);
end loop;
delete from xlsx_files;
END;
Per William Robertson's comments, the issue was there was another session which was using the procedure. This session was killed and I was able to recompile.
I've a select cursor expression with multiple inner select cursors. I wanted to check in the outer most select cursor if the inner cursor is returning any value or not.
eg.,
SELECT
CURSOR
(SELECT
CURSOR
(SELECT c.cat_name category ,
CURSOR
(SELECT
CURSOR
(SELECT grp.grpng
GROUPING ,
grp.action_group action_group ,
CURSOR
(SELECT
CURSOR
(SELECT header_id ,
order_no ,
cust_name ,
cust_phone ,
org ,
status `enter code here`,
reason
FROM headers h
WHERE h.header_id = da.header_id ) "G_HEADER"
FROM dual) "LIST_G_HEADER"
FROM action_group grp
WHERE grp.grpng = da.grpng
AND grp.action_grp = da.action_grp ) "G_ACTION"
FROM action_rep da
WHERE da.org = 'test'
AND da.cat_id = c.cat_id
ORDER BY category,
GROUPING,
reason ) "LIST_G_ACTION_GROUP"
FROM dual ) "G_CATEGORY"
FROM dual ) "LIST_G_CATEGORY" ,
c.category_name
FROM cat c
ORDER BY c.cat_name
I need to put a check to see if the result of "LIST_G_CATEGORY" cursor is null or not and if it is null then do not display that row.
P.S: please ignore the column name mismatches as the query is made up in rush to post here.
Version: Oracle 11g R2
In order to check whether the cursor is empty or not, one should fetch it first.
This means that you could crate a function (probably using SYS_REFCURSOR) that will return 1 or 0 accordingly, when the cursor is empty or not - but you should be aware of the rowtype that the cursor returns, in order to do that.
Check this references
oracle cursor expression,
similar question on stackoverflow,
check sys ref cursor is empty - stackoverflw,
ref cursor rowcount question.
I am getting sql state 42601 when executing following function. Can someone please help to resolve this error. I used this stackoverflow question to create the view from function. My function code is as below. I am trying to execute this function using select * from Test('DEPTA_');. I am getting error
SQL state: 42601
Context: PL/pgSQL function test(text) line 3 at EXECUTE statement
Function code :
create or replace function Test(authority text) returns void
as $$
BEGIN
EXECUTE
'create materialized view '||authority ||' as
WITH FINDUNDERSCORE as
(select '||authority ||' as role, position(''_'' in '||authority||') as pos ),
DISTINCT_ROLE as
( select substring('||authority ||', 0, pos) as distinctRoles from FINDUNDERSCORE where position(''_'' in '||authority ||') > 1 and ''authority '' not like ''ROLE%''
union select substring('||authority ||', pos+1, length('||authority ||')) as distinctRoles from FINDUNDERSCORE where position(''_'' in '||authority ||') > 1 and '||authority ||' not like ''ROLE%''
union select '||authority ||' from FINDUNDERSCORE
),
ORIGINAL_ID as
(select ROW_NUMBER() over(order by distinctRoles asc) as id, distinctRoles from DISTINCT_ROLE order by distinctRoles asc),
mapped_Id as
( select (case when oi.distinctroles ~ asid.sid then asid.id end ) as newId, oi.id,oi.distinctroles,asid.sid, asid.id from original_id oi,acl_sid asid ),
AGGREGATE_NEWID as
(select mi.newid,max(sid) sid, max(distinctroles) distinctroles, array_to_string(array_agg(mi.distinctroles),',') as aggregatedroles from mapped_id mi where mi.newid is not null group by mi.newid ),
MATCH_ACL_ENTRY as
(select * from acl_entry ae join AGGREGATE_NEWID asid on ae.sid = asid.newid and granting is true and bitand(cast(ae.mask as bit(32)), cast(1 as bit(32)) ) = cast(1 as bit(32)) ) ,
MATCH_ACL_OBJECT_IDENTITY as
(select * from ACL_OBJECT_IDENTITY acl join MATCH_ACL_ENTRY asid on acl.id = asid.acl_object_identity),
MATCH_ACL_PLATE as
(select p.id, p.plate_barcode, p.plate_size, p.plate_id, acl.aggregatedroles, substring(acl.aggregatedroles,0,position(',' in acl.aggregatedroles)) as parentrole,
substring(acl.aggregatedroles,position(',' in acl.aggregatedroles)+1, length(acl.aggregatedroles)) as childrole from plate p join MATCH_ACL_OBJECT_IDENTITY acl on acl.object_id_identity = p.id)
select id,plate_barcode,plate_size,plate_id from MATCH_ACL_PLATE';
END;
$$ LANGUAGE plpgsql;
You've messed up at least three times while concatenating strings for EXECUTE statement. The SQL used to create view does not seem to be a valid one due to incorrect concatenation again.
My recommendation to you:
1st build a valid sql for view creation
2nd carefully replace required parts with variable concatenation
3rd you can always check log file to find out more information about errors you get
Good luck!
If anyone runs across same situation i solved this problem by adding three single quotes around parameter name which i want to consider as single quoted string
EXECUTE
'create materialized view '||authority||' as
WITH FINDUNDERSCORE as
(select position(''_'' in '''||authority||''') as pos )
...