BUG: ORA_00913 Oracle Error - Too many values - oracle

The below code is in stored procedure, and they told me to convert it into nested loops and try running it.
insert into PRICEVIEW_RATE_PLAN_PROC (
SSR_CODE
,CORRIDOR_PLAN_ID
,CORRIDOR_PLAN_DESCRIPTION
,USAGE_TYPE
,PRODUCT
,JURISDICTION
,PROVIDER
,RATE_PERIOD
,FLAGFALL
,RATE
,RATEBAND
,NUMSECS
,BAND_RATE
,ACTIVE_DT
,INACTIVE_DT
)
select /*+ use_hash(rate_usage_overrides,corridor_plan_id_values,product_elements,descriptions,jurisdictions,rate_usage_bands_overrides) */
distinct decode(a.corridor_plan_id, 0, '''', (
select c.short_display
from corridor_plan_id_values c
where a.corridor_plan_id = c.corridor_plan_id
)) as SSR_CODE
,a.corridor_plan_id as CORRIDOR_PLAN_ID
,decode(a.corridor_plan_id, 0, '''', (
select d.display_value
from corridor_plan_id_values d
where a.corridor_plan_id = d.corridor_plan_id
)) as CORRIDOR_PLAN_DESCRIPTION
,decode(a.type_id_usg, 0, '''', (
select f.description_text
from usage_types e
,descriptions f
where a.type_id_usg = e.type_id_usg
and e.description_code = f.description_code
)) as USAGE_TYPE
,decode(a.element_id, 0, '''', (
select h.description_text
from product_elements g
,descriptions h
where a.element_id = g.element_id
and g.description_code = h.description_code
)) as PRODUCT
,decode(a.jurisdiction, 0, '''', (
select j.description_text
from jurisdictions i
,descriptions j
where a.jurisdiction = i.jurisdiction
and j.description_code = i.description_code
)) as JURISDICTION
,decode(a.provider_class, 0, '''', (
select k.display_value
from provider_class_values k
where a.provider_class = k.provider_class
)) as PROVIDER
,decode(a.rate_period, '' 0 '', '''', (
select l.display_value
from rate_period_values l
where a.rate_period = l.rate_period
)) as RATE_PERIOD
,(a.FIXED_CHARGE_AMT / 100) + (a.ADD_FIXED_AMT / 10000000) as FLAGFALL
,(a.ADD_UNIT_RATE / 10000000) * 60 as RATE
,b.RATEBAND as RATEBAND
,b.NUM_UNITS as NUMSECS
,(b.UNIT_RATE / 10000000) * 60 as BAND_RATE
,a.ACTIVE_DT as ACTIVE_DT
,a.INACTIVE_DT as INACTIVE_DT
from rate_usage_overrides a
,rate_usage_bands_overrides b
where a.seqnum = b.seqnum(+);
I converted above code to nested loop and please find below converted nested loop and When I try to run this script below, it is prompting me an error: too many values. Can you tell me what exactly problem is
insert into PRICEVIEW_RATE_PLAN_PROC(
SSR_CODE,
CORRIDOR_PLAN_DESCRIPTION,
USAGE_TYPE,
PRODUCT,
JURISDICTION,
PROVIDER,
RATE_PERIOD,
FLAGFALL,
RATE,
RATEBAND,
NUMSECS,
BAND_RATE,
ACTIVE_DT,
INACTIVE_DT
) VALUES (
(select c.short_display AS SSR_CODE from rate_usage_overrides a,corridor_plan_id_values c where a.corridor_plan_id = c.corridor_plan_id),
(select d.display_value AS CORRIDOR_PLAN_DESCRIPTION from rate_usage_overrides a ,corridor_plan_id_values d where a.corridor_plan_id = d.corridor_plan_id),
(select f.description_text AS USAGE_TYPE from rate_usage_overrides a ,usage_types e, descriptions f where a.type_id_usg = e.type_id_usg and e.description_code = f.description_code ),
(select h.description_text AS PRODUCT from rate_usage_overrides a, product_elements g,descriptions h where a.element_id = g.element_id and g.description_code = h.description_code ),
(select j.description_text AS JURISDICTION from rate_usage_overrides a, jurisdictions i,descriptions j where a.jurisdiction = i.jurisdiction and j.description_code = i.description_code),
(select k.display_value AS PROVIDER from rate_usage_overrides a ,provider_class_values k where a.provider_class = k.provider_class),
(select l.display_value AS RATE_PERIOD from rate_usage_overrides a ,rate_period_values l where a.rate_period = l.rate_period),
(select (a.FIXED_CHARGE_AMT/100) + (a.ADD_FIXED_AMT/10000000) AS FLAGFALL from rate_usage_overrides a AS ACTIVE_DT),
(select (a.ADD_UNIT_RATE/10000000) * 60 AS RATE from rate_usage_overrides a),
(select b.RATEBAND AS RATEBAND from rate_usage_bands_overrides b),
(select b.NUM_UNITS AS NUMSECS from rate_usage_bands_overrides b),
(select (b.UNIT_RATE/10000000) * 60 AS BAND_RATE from rate_usage_bands_overrides b),
(select a.ACTIVE_DT,a.seqnum,b.seqnum AS ACTIVE_DT from rate_usage_overrides a, rate_usage_bands_overrides b where a.seqnum = b.seqnum(+)),
(select a.INACTIVE_DT,a.seqnum,b.seqnum AS INACTIVE_DT from rate_usage_overrides a, rate_usage_bands_overrides b where a.seqnum = b.seqnum(+))

Here is your mistake
(select a.ACTIVE_DT,a.seqnum,b.seqnum AS ACTIVE_DT from rate_usage_overrides a, rate_usage_bands_overrides b where a.seqnum = b.seqnum(+)),
(select a.INACTIVE_DT,a.seqnum,b.seqnum AS INACTIVE_DT from rate_usage_overrides a, rate_usage_bands_overrides b where a.seqnum = b.seqnum(+))
both the query will return 3 field but insert specify only one column that's why u are getting this error. and by the way this is not a bug

Run Individual queries with c.corridor_plan_id from 1st query on wards and check at least one query returns more than one value

Related

How can I extract columns name from row value of another table(oracle sql)?

I have 2 tables:
table1
no
a
b
c
x1
2
3
4
x2
10
11
12
x3
20
21
22
table2
from_val
in_out
cf_pv
term
a
out
cf
b
b
out
pv
b
c
in
cf
e
Define sum_out is sum of a, b, c in table1 with condition in_out='out' in table2 and sum_cf is sum of a, b, c in table1 with condition cf_pv='cf' in table2.
Shortly, values of from_val in table2 are columns name i.e. a, b, c in table1.
How can I extract and calculate sum_out or sum_cf of every no in Oracle?
sum_out of x1 = 2 + 3
sum_out of x2 = 10 + 11
sum_out of x3 = 20 + 21
sum_cf of x1 = 2 + 4
sum_cf of x2 = 10 + 12
sum_cf of x3 = 20 + 22
Thanks!
'''''''''''''''''''''''''''''''''''''''''''''
in additional,
i want to calculate
sum_out and cf of x1= 2 (=a)
sum_out and cf of x2= 10 (=b)
sum_out and cf of x3= 20 (=c)
Sample data
WITH
tbl_1 AS
(
Select 'x1' "COL_NO", 2 "A", 3 "B", 4 "C" From Dual Union All
Select 'x2' "COL_NO", 10 "A", 11 "B", 12 "C" From Dual Union All
Select 'x3' "COL_NO", 20 "A", 21 "B", 22 "C" From Dual
),
tbl_2 AS
(
Select 'A' "FROM_VAL", 'out' "IN_OUT", 'cf' "CF_PV", 'begin' "TERM" From Dual Union All
Select 'B' "FROM_VAL", 'out' "IN_OUT", 'pv' "CF_PV", 'begin' "TERM" From Dual Union All
Select 'C' "FROM_VAL", 'in' "IN_OUT", 'cf' "CF_PV", 'end' "TERM" From Dual
),
Create CTE (formulas) that generates formulas for IN_OUT = 'out' and For CF_PV = 'cf'
formulas AS
(
Select
CASE WHEN IN_OUT = 'out' THEN IN_OUT END "IN_OUT",
LISTAGG(FROM_VAL, ' + ') WITHIN GROUP (ORDER BY FROM_VAL) OVER(PARTITION BY IN_OUT) "IN_OUT_FORMULA",
CASE WHEN CF_PV = 'cf' THEN CF_PV END "CF_PV",
LISTAGG(FROM_VAL, ' + ') WITHIN GROUP (ORDER BY FROM_VAL) OVER(PARTITION BY CF_PV) "CF_PV_FORMULA"
From
tbl_2
),
IN_OUT
IN_OUT_FORMULA
CF_PV
CF_PV_FORMULA
C
cf
A + C
out
A + B
cf
A + C
out
A + B
B
Another CTE (grid) to connect COL_NO to formulas
grid AS
(
Select
t1.COL_NO,
CASE WHEN f1.IN_OUT = 'out' THEN f1.IN_OUT END "IN_OUT", CASE WHEN f1.IN_OUT = 'out' THEN f1.IN_OUT_FORMULA END "IN_OUT_FORMULA",
CASE WHEN f1.CF_PV = 'cf' THEN f1.CF_PV END "CF_PV", CASE WHEN f1.CF_PV = 'cf' THEN f1.CF_PV_FORMULA END "CF_PV_FORMULA"
From
tbl_1 t1
Left Join
formulas f1 ON(f1.IN_OUT Is Not Null AND f1.CF_PV Is Not Null)
)
COL_NO
IN_OUT
IN_OUT_FORMULA
CF_PV
CF_PV_FORMULA
x1
out
A + B
cf
A + C
x2
out
A + B
cf
A + C
x3
out
A + B
cf
A + C
Main SQL to get the final result
SELECT
g.COL_NO,
g.IN_OUT,
g.IN_OUT_FORMULA,
CASE WHEN g.IN_OUT = 'out' And INSTR(IN_OUT_FORMULA, 'A') > 0 THEN A ELSE 0 END +
CASE WHEN g.IN_OUT = 'out' And INSTR(IN_OUT_FORMULA, 'B') > 0 THEN B ELSE 0 END +
CASE WHEN g.IN_OUT = 'out' And INSTR(IN_OUT_FORMULA, 'C') > 0 THEN C ELSE 0 END "CALC_OUT",
--
g.CF_PV,
g.CF_PV_FORMULA,
CASE WHEN g.CF_PV = 'cf' And INSTR(CF_PV_FORMULA, 'A') > 0 THEN A ELSE 0 END +
CASE WHEN g.CF_PV = 'cf' And INSTR(CF_PV_FORMULA, 'B') > 0 THEN B ELSE 0 END +
CASE WHEN g.CF_PV = 'cf' And INSTR(CF_PV_FORMULA, 'C') > 0 THEN C ELSE 0 END "CALC_CF"
FROM
grid g
INNER JOIN
tbl_1 t1 ON(g.COL_NO = t1.COL_NO)
R e s u l t :
COL_NO
IN_OUT
IN_OUT_FORMULA
CALC_OUT
CF_PV
CF_PV_FORMULA
CALC_CF
x1
out
A + B
5
cf
A + C
6
x2
out
A + B
21
cf
A + C
22
x3
out
A + B
41
cf
A + C
42

how to filter out null value then compare in oracle

I tried this, and it works,
SELECT name
FROM
(SELECT name,LENGTH FROM river WHERE LENGTH IS NOT NULL
)
WHERE LENGTH >= ALL
(SELECT LENGTH FROM
(SELECT name,LENGTH FROM river WHERE LENGTH IS NOT NULL
)
)
but my final code would be like this:
SELECT a.name,
a.length
FROM
(SELECT name,LENGTH FROM river WHERE LENGTH IS NOT NULL
) a,
geo_river b,
encompasses c
WHERE a.length >= ALL
(SELECT a2.LENGTH
FROM
(SELECT name,LENGTH FROM river WHERE LENGTH IS NOT NULL
) a2
)
AND a.name = b.river
AND b.country = c.country
AND c.continent = 'America'
this is really complicated.
Is there an easy way to let
(SELECT name,LENGTH FROM river WHERE LENGTH IS NOT NULL)
be river, so I don't need to use this
(SELECT name,LENGTH FROM river WHERE LENGTH IS NOT NULL)
two times.
If you want to simplify your code writing, you can use WITH:
with viewA as (SELECT name,LENGTH FROM river WHERE LENGTH IS NOT NULL )
SELECT a.name,
a.length
FROM
viewA a,
geo_river b,
encompasses c
WHERE a.length >= ALL
(SELECT a2.LENGTH
FROM
viewA a2
)
AND a.name = b.river
AND b.country = c.country
AND c.continent = 'America'
Using a single table scan:
SELECT name,
length
FROM (
SELECT name,
length,
RANK() OVER ( ORDER BY length DESC ) AS rnk
FROM river
)
WHERE rnk = 1;
So your code would then be:
SELECT a.name,
a.length
FROM (
SELECT name,
length
FROM (
SELECT name,
length,
RANK() OVER ( ORDER BY length DESC ) AS rnk
FROM river
)
WHERE rnk = 1
) a
INNER JOIN
geo_river b
ON ( a.name = b.river )
INNER JOIN
encompasses c
ON ( b.country = c.country )
WHERE c.continent = 'America';
I don't think you need to filter out null lengths as they won't show up if you subset on length (i.e. when comparing NULL values without using the NVL function the comparison will always evaluate to false and not show the row). So something simple such as:
Select a.name, a.length
from river a, geo_river b, encompasses c
WHERE a.length > 0
AND a.name = b.river
AND b.country = c.country
AND c.continent = 'America'
;
Will do the trick

Convert SQL Server CTE into Oracle CTE

Here is the SQL Server CTE, trying to convert to Oracle CTE or regular oracle query..
;with cte as
(Select AC, M, Y, D, E, F, CD
from tblA
WHere
(Y = YEAR(GETDATE()) and M = Month(dateadd(month, -1, GETDATE())))
),
cte2 as
(Select A.AC,Max(A.Y)as Y, Max(A.M) as M, Max(A.CD) as CD
from tbl A
Inner join cte B on B.AC = A.AC
WHere A.CD is Not Null and B.CD is Null
Group by A.AC)
, cte3 as
(Select C.AC, C.Y, C.M, C.D, C.E, C.F, C.CD
from tblA C
Inner join cte2 D on C.AC = D.AC and C.Y= D.Y and C.M = D.M and
D.CD = C.CD
)
select * from cte
union
select * from cte3;
Assuming you didn't have the m and y columns reversed on purpose in your cte/cte3 select lists, I think you could rewrite your query as:
with cte1 as (select a.ac,
a.m,
a.y,
a.d,
a.e,
a.f,
a.cd,
max(case when a.cd is not null and b.cd is not null then a.y end) over (partition by a.ac) max_y,
max(case when a.cd is not null and b.cd is not null then a.m end) over (partition by a.ac) max_m,
max(case when a.cd is not null and b.cd is not null then a.cd end) over (partition by a.ac) max_cd
from tbla a
left outer join tblb b on (a.ac = b.ac))
select ac,
m,
y,
d,
e,
f,
cd
from cte1
where (y = to_char(sysdate, 'yyyy')
and m = to_char(add_months(sysdate, -1), 'mm'))
or (y = max_y
and m = max_m
and cd = max_cd);
You haven't provided any sample data, so I can't test, but it would be worth converting the date functions to their SQL Server equivalents and testing to make sure the data returned is the same.
This way, you're not querying the same table 3 times, which should improve the performance some.

Duplicating rows in an oracle query

I am to create a query which will be used for printing labels in our project and find it difficult since the count of the number of labels is based on a string. I have made a query that looks like this:
SELECT
wipdatavalue
, containername
, l
, q as qtybox
, d
, qtyperbox AS q
, productname
, dt
, dsn
, CASE
WHEN instr(wipdatavalue, '-') = 0
THEN
to_number(wipdatavalue)
ELSE
to_number(substr(wipdatavalue, 1, instr(wipdatavalue, '-') - 1))
END AS una
, CASE
WHEN instr(wipdatavalue, '-') = 0
THEN
to_number(wipdatavalue)
ELSE
to_number(substr(wipdatavalue, instr(wipdatavalue, '-') + 1))
END AS dulo
, ROW_NUMBER() OVER (ORDER BY containername) AS n
, count(*) over() m
FROM trprinting_ls
WHERE containername = 'TRALTESTU0A'
GROUP BY wipdatavalue, containername, l, q, d, qtyperbox, productname, dt, dsn
ORDER BY wipdatavalue
The query above will result to below:
But actually, I have to display the first Item (Wipdatavalue 1-4) not only once but four times to look something like this:
I have tried another query that runs fine but when I try to load it in our project, it does not print the label. We found out that it is because of the WITH statement and we don't know why. The query is:
WITH DATA (WIPDATAVALUE, CONTAINERNAME, L, Q, D, QTYBOX, PRODUCTNAME, DT, una, dulo, m1, n)
AS (SELECT WIPDATAVALUE, CONTAINERNAME, L, Q, D, QTYBOX, PRODUCTNAME, DT, una, dulo,(dulo - una) + 1 AS m1,una n
FROM (SELECT WIPDATAVALUE, CONTAINERNAME, L, Q, D, QTYPERBOX AS QTYBOX, PRODUCTNAME, DT,
CASE
WHEN instr(wipdatavalue, '-') = 0
THEN
to_number(wipdatavalue)
ELSE
to_number(substr(wipdatavalue, 1, instr(wipdatavalue, '-') - 1))
END AS una,
CASE
WHEN instr(wipdatavalue, '-') = 0
THEN
to_number(wipdatavalue)
ELSE
to_number(substr(wipdatavalue, instr(wipdatavalue, '-') + 1))
END AS dulo
FROM trprinting_ls
WHERE containername = 'TRALTESTU0A'
)
UNION ALL
SELECT WIPDATAVALUE, CONTAINERNAME, L, Q, D, QTYBOX, PRODUCTNAME, DT, una, dulo, m1, n + 1
FROM DATA
WHERE n + 1 <= dulo)
SELECT WIPDATAVALUE, CONTAINERNAME, L, Q, D, QTYBOX, PRODUCTNAME, DT, una, dulo, n,
count(*) OVER () m
FROM DATA
ORDER BY n, wipdatavalue
Thanks guys for helping out.
Try this
select *
from your_data
start with instr(Wipdatavalue, '1') > 0
connect by level between regexp_substr(Wipdatavalue, '^\d+')
and regexp_substr(Wipdatavalue, '\d+$')
It's a simplified example
The regexp_substr can be replaced with substr and instr if you like (may also be faster)
Here is a sqlfiddle demo
Try this Query
select column_name, count(column_name)
from table
group by column_name
having count (column_name) > 1;

Selecting a sum from a correlated subquery - Oracle

I'm trying to change my code to have Oracle do all the heavy lifting. Originally, I had a function which did the following:
<!--- get common data --->
<cfquery name="getCommon">
SELECT x, NVL(SUM(y), 0) as y
FROM table_1
WHERE z between #this# and #that#
GROUP BY x
</cfquery>
<!--- place common values into a struct --->
<cfset oCommon = StructNew() >
<cfloop query="getCommon">
<cfset oCommon[x] = y >
</cfloop>
<!--- get records to loop through --->
<cfquery name="getSomething">
SELECT a, b, c/d as e from (
SELECT DISTINCT t2.a,
t2.b,
c,
sum(d)as d
FROM table_2 t2
LEFT JOIN table_3 t3
ON t2.a = t3.a
AND t2.b = t3.b
GROUP BY t2.a, t2.b, c
)
</cfquery>
<!--- loop through the results --->
<cfloop query="getSomething">
<!--- do an update to the target table if conditions are met --->
<!--- calculate my important new value --->
<cfset new_value = #getSomething.e# * #oCommon[b]# >
<!--- finally, insert my new values into the target table --->
<cfquery name="insertTarget">
INSERT INTO target_table(
a,
b,
c
)
VALUES (
#getSomething.a#,
#getSomething.b#,
#new_value#
)
</cfquery>
</cfloop>
I've already figured out how to use Oracle's MERGE to replace the update statement in the loop. My problem is the SQL to replace the insert statement. I'd like to be able to calculate the new value inside the SQL... once I get that, I think I can figure out the MERGE/insert part fairly easily.
So I want to do something like:
SELECT a, b, c/d*y as e from (
SELECT DISTINCT t2.a,
t2.b,
c,
sum(d)as d,
(
SELECT y FROM (
SELECT x, NVL(SUM(y), 0) as y
FROM table_1
WHERE z between #this# and #that#
AND x = t2.a
GROUP BY x
)
)
FROM table_2 t2
LEFT JOIN table_3 t3
ON t2.a = t3.a
AND t2.b = t3.b
GROUP BY t2.a, t2.b, c
)
which, perhaps obviously, doesn't work. Currently I get an ORA-00904: "t2"."a": Invalid Identifier, which isn't surprising.
So, I basically need to figure out how to get the sum of y from table_1, correlated by x = table_2.a, into the original getSomething query.
Edit: I tried this, but it's not quite right:
SELECT a, b, c/d*y as e from (
SELECT DISTINCT t2.a,
t2.b,
c,
sum(d)as d,
NVL(SUM(y), 0) as y
FROM table_2 t2
LEFT JOIN table_3 t3
ON t2.a = t3.a
AND t2.b = t3.b
LEFT JOIN table_1 t1
ON t1.x = t2.a
AND t1.z between #this# and #that#
GROUP BY t2.a, t2.b, c
)
You could write your query like this:
SELECT a, b, c / d * y AS e
FROM (SELECT DISTINCT t2.a,
t2.b,
c,
sum(d) AS d,
v.y
FROM table_2 t2
LEFT JOIN table_3 t3
ON t2.a = t3.a
AND t2.b = t3.b
LEFT JOIN (SELECT x, nvl(sum(y), 0) AS y
FROM table_1
WHERE z BETWEEN #this# AND #that#
GROUP BY x) v
ON t2.a = v.x
GROUP BY t2.a, t2.b, c, v.y)
The optimizer should be able to push the predicate t2.a = v.x into the subquery if it is convenient (for example if there is an index on table_1.x).
The sql sentence that worked for me is te following:
Select p.id,p.name, ( select sum(quantity) from details d where d.idproduct=p.id) sum from products p

Resources