Function returning a table inside where clause [message #450178] |
Mon, 05 April 2010 11:14  |
asairam
Messages: 11 Registered: April 2010
|
Junior Member |
|
|
DECLARE
cnt number(10);
BEGIN
SELECT COUNT(*) INTO CNT FROM TBL_ADDRESS WHERE ADDRESS_ZIP
IN (SELECT * FROM TABLE(MY_PACK.STR2TBL('46227')));
DBMS_OUTPUT.PUT_LINE (cnt);
END;
MY_PACK.STR2TBL() is a function which takes '|' delimited string,
extracts values and returns a table of zipcodes. The function works
fine and returns 46227 but the count returned is 0 instead of
280(count returned by replacing inner select with '46227').
Cluesless so far on whats wrong. Any ideas please? Please help.
Thanks
|
|
|
|
Re: Function returning a table inside where clause [message #450190 is a reply to message #450179] |
Mon, 05 April 2010 12:30   |
asairam
Messages: 11 Registered: April 2010
|
Junior Member |
|
|
Thank you for the response. Thats surprising to hear. Isnt it the same as
SELECT * FROM
TABLE1 A
WHERE A.Col1 IN (SELECT B.Col1 FROM TABLE2 B)
If it is not the same, then do you have any idea on how to accept a delimited string like 'zip1|zip2|zip3' and convert it into a filter condition in WHERE clause?
Thanks.
|
|
|
|
Re: Function returning a table inside where clause [message #450195 is a reply to message #450192] |
Mon, 05 April 2010 12:54   |
asairam
Messages: 11 Registered: April 2010
|
Junior Member |
|
|
Hi,
May be I was not clear in the last message. I was not talking about the delimited values being stored in a table column. Column stores only one zipcode value. I was talking about stored procedure.
I have a stored procedure which accepts a zipcode in a parameter and return all addresses in that zipcode. If it is more than one zipcode then a '|' delimited string is passed in parameter as shown earlier.
So procedure parameter value can be '46227' or '46227|46204|46253'.
So inside the procedure, I need to parse the '|' delimited values, extract zipcodes and get all the addresses in those zipcodes.
Hope I am clear now.
Thanks
|
|
|
|
Re: Function returning a table inside where clause [message #450197 is a reply to message #450178] |
Mon, 05 April 2010 13:03   |
flyboy
Messages: 1903 Registered: November 2006
|
Senior Member |
|
|
asairam wrote on Mon, 05 April 2010 18:14DECLARE
cnt number(10);
BEGIN
SELECT COUNT(*) INTO CNT FROM TBL_ADDRESS WHERE ADDRESS_ZIP
IN (SELECT * FROM TABLE(MY_PACK.STR2TBL('46227')));
DBMS_OUTPUT.PUT_LINE (cnt);
END;
MY_PACK.STR2TBL() is a function which takes '|' delimited string,
extracts values and returns a table of zipcodes. The function works
fine and returns 46227 but the count returned is 0 instead of
280(count returned by replacing inner select with '46227').
Cluesless so far on whats wrong. Any ideas please? Please help.
Thanks
What does that inner SELECT return?
What is the data type of MY_PACK.STR2TBL() return value?
Are you sure it returns strings without any whitespaces?
|
|
|
Re: Function returning a table inside where clause [message #450199 is a reply to message #450196] |
Mon, 05 April 2010 13:16   |
asairam
Messages: 11 Registered: April 2010
|
Junior Member |
|
|
Source code:
CREATE OR REPLACE TYPE STRTABLETYPE IS TABLE OF VARCHAR2(255);
/
FUNCTION STR2TBL
(P_STR IN VARCHAR2,
P_DELIM IN VARCHAR2 DEFAULT '|'
)
RETURN STRTABLETYPE
AS
L_STR VARCHAR2(2000) DEFAULT P_STR || P_DELIM;
L_N NUMBER;
L_DATA STRTABLETYPE := STRTABLETYPE();
BEGIN
LOOP
L_N := INSTR( L_STR, P_DELIM );
EXIT WHEN (NVL(L_N,0) = 0);
L_DATA.EXTEND;
L_DATA( L_DATA.COUNT ) := LTRIM(RTRIM(SUBSTR(L_STR,1,L_N-1)));
L_STR := SUBSTR( L_STR, L_N+LENGTH(P_DELIM) );
END LOOP;
RETURN L_DATA;
END;
|
|
|
Re: Function returning a table inside where clause [message #450200 is a reply to message #450197] |
Mon, 05 April 2010 13:18   |
asairam
Messages: 11 Registered: April 2010
|
Junior Member |
|
|
Thanks for the response. Inner select is the one after IN.
The function returns a table of varchars. Heres the source code.
CREATE OR REPLACE TYPE STRTABLETYPE IS TABLE OF VARCHAR2(255);
/
FUNCTION STR2TBL
(P_STR IN VARCHAR2,
P_DELIM IN VARCHAR2 DEFAULT '|')
RETURN STRTABLETYPE
AS
L_STR VARCHAR2(2000) DEFAULT P_STR || P_DELIM;
L_N NUMBER;
L_DATA STRTABLETYPE := STRTABLETYPE();
BEGIN
LOOP
L_N := INSTR( L_STR, P_DELIM );
EXIT WHEN (NVL(L_N,0) = 0);
L_DATA.EXTEND;
L_DATA( L_DATA.COUNT ) := LTRIM(RTRIM(SUBSTR(L_STR,1,L_N-1)));
L_STR := SUBSTR( L_STR, L_N+LENGTH(P_DELIM) );
END LOOP;
RETURN L_DATA;
END;
|
|
|
|
|
Re: Function returning a table inside where clause [message #450203 is a reply to message #450201] |
Mon, 05 April 2010 13:25   |
cookiemonster
Messages: 13967 Registered: September 2008 Location: Rainy Manchester
|
Senior Member |
|
|
BlackSwan wrote on Mon, 05 April 2010 19:20SQL SELECT knows nothing about STRTABLETYPE datatype
It's been created as a SQL type so that's manifestly wrong.
That should have been obvious from the fact that the select gives the wrong data rather than an error.
@asairam - what's the result of the following:
SELECT * FROM TABLE(MY_PACK.STR2TBL('46227'));
SELECT COUNT(*)
FROM TBL_ADDRESS
WHERE ADDRESS_ZIP IN ('46227');
|
|
|
|
|
|
|
Re: Function returning a table inside where clause [message #450209 is a reply to message #450208] |
Mon, 05 April 2010 14:11   |
asairam
Messages: 11 Registered: April 2010
|
Junior Member |
|
|
Sure. I didnt know that you were asking me the results of those queries. Sorry about that.
The first query result is :
SELECT * FROM TABLE(MY_PACK.STR2TBL('46227'));
COLUMN_VALUE
-------------------
46227
The second query result is
SELECT COUNT(*)
FROM TBL_ADDRESS
WHERE ADDRESS_ZIP IN ('46227');
COUNT(*)
----------------------
280
Thanks.
|
|
|
Re: Function returning a table inside where clause [message #450211 is a reply to message #450209] |
Mon, 05 April 2010 14:14   |
 |
ramoradba
Messages: 2457 Registered: January 2009 Location: AndhraPradesh,Hyderabad,I...
|
Senior Member |
|
|
SELECT COUNT(*)
FROM TBL_ADDRESS
WHERE ADDRESS_ZIP IN ('46227');
COUNT(*)
----------------------
280
Then whats the value of
SELECT COUNT(*)
FROM TBL_ADDRESS
WHERE ADDRESS_ZIP IN (SELECT * FROM TABLE(MY_PACK.STR2TBL('46227'))); ?
SQL> select count(*) from emp
2 where deptno=10;
COUNT(*)
----------
3
SQL> select count(*) from emp
2 where deptno in (select * FROM TABLE(in_list_pipe('10')));
COUNT(*)
----------
3
sriram
[Updated on: Mon, 05 April 2010 14:16] Report message to a moderator
|
|
|
|
Re: Function returning a table inside where clause [message #450216 is a reply to message #450213] |
Mon, 05 April 2010 14:21   |
asairam
Messages: 11 Registered: April 2010
|
Junior Member |
|
|
You can see the usage of type and function you defined and the results Sriram:
SELECT COUNT(*) FROM TBL_ADDRESS WHERE ADDRESS_ZIP IN
(SELECT * FROM TABLE(in_list_pipe('46227|46204')));
SELECT COUNT(*) FROM TBL_ADDRESS WHERE ADDRESS_ZIP IN
('46227','46204');
COUNT(*)
----------------------
0
COUNT(*)
----------------------
541
|
|
|
Re: Function returning a table inside where clause [message #450219 is a reply to message #450178] |
Mon, 05 April 2010 14:37   |
asairam
Messages: 11 Registered: April 2010
|
Junior Member |
|
|
Dear All,
I just found out the root cause. The ZIPCode column I was querying is of CHAR type whereas the table type I created has VARCHAR2 type and hence the issue. When I change the type as char
CREATE OR REPLACE TYPE STRTABLETYPE AS TABLE OF CHAR(10);
then the count has come correct.
Now this leaves two questions for me:
1. How does this work when we pass the values directly as '46227'?
2.What about the SQL and PL/SQL type issue which BlackSwan has pointed?
Quote:
SQL SELECT knows nothing about STRTABLETYPE datatype
SQL is different than PL/SQL and you can not use PL/SQL datatype in vanilla SQL statements
Thank you all for your time and patience.
Sairam
|
|
|
Re: Function returning a table inside where clause [message #450223 is a reply to message #450219] |
Mon, 05 April 2010 15:20   |
cookiemonster
Messages: 13967 Registered: September 2008 Location: Rainy Manchester
|
Senior Member |
|
|
asairam wrote on Mon, 05 April 2010 20:37
1. How does this work when we pass the values directly as '46227'?
Because '46227' can be transformed into a char(10) by adding a few spaces, but a varchar(255) can't. You're always going to have trouble when comparing a char to a varchar. I'd convert your char column to varchar if at all possible. Read up on impicit type convsersion in the documentation if you want more details.
asairam wrote on Mon, 05 April 2010 20:37
2.What about the SQL and PL/SQL type issue which BlackSwan has pointed?
Quote:
SQL SELECT knows nothing about STRTABLETYPE datatype
SQL is different than PL/SQL and you can not use PL/SQL datatype in vanilla SQL statements
There is no issue, Blackswan imagined it.
|
|
|
|