i'm working with stored procedures, i have a query that should bring one specific id
SELECT * into SID_INCOMING FROM
(
SELECT SID
FROM TBL_INCOMING
WHERE XKEY = ''||nro_tarjetatmp||'_'||fecha_hr_trasacfinal||'_'||datos_referencia_adquirentetmp||''
AND CODIGO_AUTORIZACION IN(''||codigo_autorizacion||'')
AND MIT IN(''||mit||'')
ORDER BY SID ASC
) WHERE ROWNUM <= 1;
the variables values are in order
4946110112060005_200116_74064350165099586691985
536018
05
when it's executed i get this result
but when i execute the same query with the same parameters i get this result
and this is the one i sould get with the procedure, so why is this happening?
it seems to me, that the sp is not considering the second and third parameter
any help is welcome, thanks
You need to use aliases to avoid your problem with AND MIT IN(''||mit||''): this predicate compares column MIT with itself.
SO just add aliases:
SELECT * into SID_INCOMING FROM
(
SELECT SID
FROM TBL_INCOMING ti
WHERE ti.XKEY = ''||your_proc_name.nro_tarjetatmp||'_'||your_proc_name.fecha_hr_trasacfinal||'_'||your_proc_name.datos_referencia_adquirentetmp||''
AND ti.CODIGO_AUTORIZACION IN(''||your_proc_name.codigo_autorizacion||'')
AND ti.MIT IN(''||your_proc_name.mit||'')
ORDER BY ti.SID ASC
) WHERE ROWNUM <= 1;
Also why do you add ''||? It doesn't add anything into your variables, but forces impicit type conversion in cases when they are not varchar2/char data types.
Could you show the results of "describe TBL_INCOMING" please? Since looks like CODIGO_AUTORIZACION is a number data type and probably MIT is number too.
Related
I know the right syntax for having a function definition in the WITH clause. I know the right syntax for having a subquery in the WITH clause. But I have been unable to find an example of having a subquery and a function definition in the WITH clause of a SELECT statement.
If I have:
with totals as ( select colum_name from some_table )
select sum(column_name) from totals;
How do I add a function definition in the WITH clause?
Since you can't find much/anything about this from Oracle, I don't think it is a good idea to use it. Anyway, this works in 18.1:
WITH
FUNCTION with_plus(p IN NUMBER) RETURN NUMBER IS
BEGIN
RETURN p + 1;
END;
FUNCTION with_min(p IN NUMBER) RETURN NUMBER IS
BEGIN
RETURN p - 1;
END;
qry1 AS (
SELECT with_plus(10) plus
FROM DUAL
),
qry2 AS (
SELECT plus, with_min(10) min
FROM qry1
)
SELECT *
FROM qry2
;
/
So don't forget the slash / at the end.
If you ever find out how to put this whole block in a subquery, please let me know
I don't think there's any such restriction. However, I suspect that your problem has to do with column aliasing. Here's what worked for me:
with totals as (select sum(column_name) c1 from some_table)
select c1 from totals;
Oracle might have complained because you were trying to do something like:
with totals as (select sum(column_name) from some_table)
select sum(column_name) from totals;
Unfortunately, this is a consequence of name resolution. The subquery's column will get named "sum(column_name)". Since sum is a function, there's no way to reference that column name without Oracle thinking you're referencing the function. You have to give it another name in order to reference it anywhere else.
Edit: It seems that you want to define a function as if you would a view subquery. I don't think anything like this is possible. View subqueries really only perform textual substitution.
PL/SQL functions require a whole different parser, name resolution, compilation process, etc. Having them work in queries alone is hard enough.
Sorry to say, but you'd have to define your packages/procedures/functions normally.
I'm comfortable with SQL Server, but not so much with Oracle.
I've got a query that looks something like the following:
SELECT umr.region, payee_name, COUNT, corporate_office_name
FROM payers, offices,
(
SELECT region, h.payee_name, COUNT, company_name FROM someTable h, someTable2
GROUP BY region, h.payee_name, company_name
) umr
WHERE ...
I know that the example isn't complete, but the key to the question is what is the COUNT in the SELECT statement telling Oracle to do?
I'd say it means there's a column called count in one of the tables.
I have a query that in the select statement uses a custom built function to return one of the values.
The problem I have is every now and then this function will error out because it returns more than one row of information. SQL Error: ORA-01422: exact fetch returns more than requested number of rows
To further compound the issue I have checked the table data within the range that this query should be running and can't find any rows that would duplicate based on the where clause of this Function.
So I would like a quick way to identify on which Row of the original query this crashes so that I can take the values from that query that would be passed into the function and rebuild the Functions query with these values to get it's result and see which two or more rows are returned.
Any ideas? I was hoping there could be a way to force Oracle to process one row at a time until it errors so you can see the results UP to the first error.
Added the code:
FUNCTION EFFPEG
--Returns Effective Pegged Freight given a Effdate, ShipTo, Item
DATE1 IN NUMBER -- Effective Date (JULIANDATE)
, SHAN IN NUMBER -- ShipTo Number (Numeric)
, ITM IN NUMBER -- Short Item Number (Numeric)
, AST IN VARCHAR -- Advance Pricing type (varchar)
, MCU IN VARCHAR Default Null --ShipFrom Plant (varchar)
) RETURN Number
IS
vReturn Number;
BEGIN
Select ADFVTR/10000
into vReturn
from PRODDTA.F4072
where ADEFTJ <= DATE1
and ADEXDJ >= DATE1
and ADAN8 = SHAN and ADITM = ITM
and TRIM(ADAST) = TRIM(AST)
and ADEXDJ = (
Select min(ADEXDJ) ADEXDJ
from PRODDTA.F4072
where ADEFTJ <= DATE1
and ADEXDJ >= DATE1
and ADAN8 = SHAN
and ADITM = ITM
and TRIM(ADAST) = TRIM(AST));
Query that calls this code and passes in the values is:
select GLEXR, ORDTYPE,
EFFPEG(SDADDJ, SDSHAN, SDITM, 'PEGFRTT', SDMCU),
from proddta.F42119
I think the best way to do it is trough Exceptions.
What you need to do is to add the code to handle many rows exception in your function:
EXCEPTION
WHEN TOO_MANY_ROWS THEN
INSERT INTO ERR_TABLE
SELECT your_columns
FROM query_that_sometimes_returns_multiple_rows
In this example the doubled result will go to separated table or you can decide to simply print out with dbms_output.
An easy page to start can be this, then just google exception and you should be able to find all you need.
Hope this can help.
I have two tables seatinfo(siid,seatno,classid,tsid) and booking (bookid,siid,date,status).
I've input parameter bookDate,v_tsId ,v_clsId. I need exactly one row (bookid) to return. This query is not working. I don't no why. How can I fix it?
select bookid
into v_bookid
from booking
where (to_char(booking.bookdate,'dd-mon-yy'))=(to_char(bookDate,'dd-mon-yy'))
and status=0
and rownum <= 1
and siid in(select siid
from seatinfo
where tsid=v_tsId
and classid= v_clsId);
I also tried this:
select bookid
into v_bookid
from booking,
seatinfo
where booking.siid=seatinfo.siid
and (to_char(booking.bookdate,'dd-mon-yy'))=(to_char(bookDate,'dd-mon-yy'))
and booking.status=0
and rownum <= 1
and seatinfo.tsid=v_tsId
and seatinfo.classid= v_clsId;
Are you saying that you get an "ORA-01422: exact fetch returns more than requested number of rows" when you run both of those queries? That seems highly unlikely since you're including the predicate rownum <= 1. Can you cut and paste from a SQL*Plus session that runs just this query in a PL/SQL block and generates the error?
If you are not complaining about the error you mention in the title, and the problem is just that you're not getting the data you expect, the likely problem is that you apparently have a bookDate parameter that has the same name as a column in your table. That is not going to work. When you say
(to_char(booking.bookdate,'dd-mon-yy'))=(to_char(bookDate,'dd-mon-yy'))
you presumably mean to compare the bookDate column in the booking table against the bookDate parameter. But since column names have precedence over local variables, the left-hand side of your expression is also looking at the bookDate column in the booking table. So you're comparing a column to itself. It would make much more sense to change the name of the parameter (to, say, p_bookDate) and then write
booking.bookDate = p_bookDate
or, if you want to do the comparison ignoring the time component of the dates
trunc( booking.bookDate ) = trunc( p_bookDate )
My Oracle query produces the correct result set, but data is being presented with odd characters as you can see by the blocks in the picture below.
alt text http://lh3.ggpht.com/_VSEi5_hEznA/TDtsnM9HDnI/AAAAAAAAAD8/zoEzbEaKB9s/blocks.jpg
Any reason that you can think of as to why it would do this and what these characters actually are? Below is the query I'm using. Thanks in advance.
SELECT wmsys.wm_concat(userFirstName) AS firstNames
FROM COURSESECTION
JOIN CLASSCOORDINATOR on classcoord_sectionId = coursesect_sectionId
JOIN usr_USER on classcoord_coordinatorId = userId
GROUP BY classcoord_sectionId;
If I use the same query but use a dump(wmsys.wm_concat(columnName)) then I get the data presented in the picture below.
alt text http://lh3.ggpht.com/_VSEi5_hEznA/TDx2dle4BmI/AAAAAAAAAEM/cP6opWer-Go/concat.jpg
DUMP is my starting point when investigating character set issues.
select wmsys.wm_concat('êõôó'), dump(wmsys.wm_concat('êõôó'))
from dual connect by level < 3;
In my database (AL32UTF8 as shown by querying the NLS_CHARACTERSET parameter from v$nls_parameters), this returns as expected.
How does selecting a simple userFirstName show up ?
I'd suspect that the values have come from a multi-character set environment but have somehow been treated as single character set data.
Edited to add:
I'm able to reproduce this using the following:
select * from v$nls_parameters
where parameter = 'NLS_NCHAR_CHARACTERSET';
AL16UTF16
create table t (v nvarchar2(3));
insert into t values ('a');
select dump(v) from t;
select wmsys.wm_concat(v), v, dump(v), dump(wmsys.wm_concat(v)) from t
group by v;
To remedy, you could try casting the string to a standard VARCHAR2
select wmsys.wm_concat(cast(v as varchar2(3)))
from t
group by v;