Home » SQL & PL/SQL » SQL & PL/SQL » Using TYPE within an SQL IN statement (Oracle Database 11g Enterprise Edition Release 11.2.0.4.0)
Using TYPE within an SQL IN statement [message #635200] Tue, 24 March 2015 11:00 Go to next message
Duane
Messages: 557
Registered: December 2002
Senior Member
I'm just seeing if this can be done. I don't believe so but maybe someone has a better way of doing it.


INPUT = 'oracle.world,peoplesoft.world,home.world,remotelocation.world'

type instance_array_type is table of varchar2(50) 
  index by binary_integer;


procedure CheckInstance([color=red]Instance in instance_array_type[/color],
                        Results  out sys_refcursor) is

begin
   open Results for
     select * 
       from outages
         where instance in ([color=red]Instance[/color]);

end;

I'm using this in other packages but it's not very clean if the data has imbedded commas "," and you are trying to delimit by a comma.  Yes, I could use a different delimiter but you never know if some user will use that in the data.

select value 
  from (select substr(Instance, instr(','||Instance||',', ',', 1, rn),
               instr(','||Instance||',', ',', 1, rn + 1) - instr(','||Instance||',', ',', 1, rn) - 1) value
          from (select rownum rn 
                  from dual 
                    connect by level <= length(Instance) - length(replace(Instance,',','')) + 1))



So what am I trying to do? I'm trying to use a TYPE within a SELECT statement without using a complicated SUBSTR, INSTR select statement with multiple values.

[Updated on: Tue, 24 March 2015 11:04]

Report message to a moderator

Re: Using TYPE within an SQL IN statement [message #635201 is a reply to message #635200] Tue, 24 March 2015 11:09 Go to previous messageGo to next message
Michel Cadot
Messages: 68645
Registered: March 2007
Location: Nanterre, France, http://...
Senior Member
Account Moderator

Quote:
I'm trying to use a TYPE within a SELECT statement


OK but how will feed the typed variable from INPUT?

Here's an example to select from a type:
SQL> create table t as 
  2  select level col1, chr(ascii('A')+level-1) col2
  3  from dual 
  4  connect by level <= 10;

Table created.

SQL> select * from t;
      COL1 C
---------- -
         1 A
         2 B
         3 C
         4 D
         5 E
         6 F
         7 G
         8 H
         9 I
        10 J

10 rows selected.

SQL> declare
  2    var sys.odcinumberlist := sys.odcinumberlist (1,3,4);
  3  begin
  4    for rec in (
  5      select col1, col2 from t where col1 in (select * from table(var))
  6    ) loop
  7      dbms_output.put_line(rec.col1||': '||rec.col2);
  8    end loop;
  9  end;
 10  /
1: A
3: C
4: D

Re: Using TYPE within an SQL IN statement [message #635202 is a reply to message #635201] Tue, 24 March 2015 11:20 Go to previous messageGo to next message
Duane
Messages: 557
Registered: December 2002
Senior Member
Not sure I follow. Are you asking me how I will retrieve the values from the INPUT which would be INSTANCE? Or are you saying I can use "where instance in (select * from table(INSTANCE))";

If you are asking me how I would retrieve the values from INSTANCE, that's my question. I don't know unless I can use a SELECT * from TABLE statement.

The INPUT to INSTANCE would be something like 'oracle.world,peoplesoft.world,home.world,remotelocation.world'. I then need to grab each value from that string to serve up to the IN parameter in the SELECT statement.

Or maybe I'm missing everything you are telling me. Could be. It's been that kind of day.
Re: Using TYPE within an SQL IN statement [message #635203 is a reply to message #635202] Tue, 24 March 2015 12:20 Go to previous messageGo to next message
Michel Cadot
Messages: 68645
Registered: March 2007
Location: Nanterre, France, http://...
Senior Member
Account Moderator

I ask how do you come from "INPUT = 'oracle.world,peoplesoft.world,home.world,remotelocation.world'" to the same values in an array?
I assume you do not expect to do "Instance := 'oracle.world,peoplesoft.world,home.world,remotelocation.world';"

The rest, from Instance to Results, I gave you the way as this is the original question.

Re: Using TYPE within an SQL IN statement [message #635208 is a reply to message #635203] Tue, 24 March 2015 13:05 Go to previous messageGo to next message
Duane
Messages: 557
Registered: December 2002
Senior Member
Ah, gotcha. I was just showing what could be PASSED INTO the procedure. The IN parameter of INSTANCE might contain these values of 'oracle.world,peoplesoft.world,home.world,remotelocation.world' as its INPUT value. Unless that's not how that works using a TYPE.

Taking the data out of the equation. My question would probably be "Correct syntax of using a TYPE within a SELECT". Will what I have work? If not, what do I need to change to make it work if it can work at all?


type instance_array_type is table of varchar2(50) 
  index by binary_integer;


procedure CheckInstance(Instance in instance_array_type,
                        Results  out sys_refcursor) is

begin
   open Results for
     select * 
       from outages
         where instance in (select * from table(Instance));

end;



I'll going to try what I have shown and see if that works. From looking at your example, I believe that's what you are telling me will work. Could be wrong on that.
Re: Using TYPE within an SQL IN statement [message #635209 is a reply to message #635208] Tue, 24 March 2015 13:09 Go to previous messageGo to next message
Michel Cadot
Messages: 68645
Registered: March 2007
Location: Nanterre, France, http://...
Senior Member
Account Moderator

Quote:
I believe that's what you are telling me will work. Could be wrong on that.


No, this is what I wanted to show.

Note that if your variable and a column have the same name then you may have some problems:

Quote:
instance in (select * from table(Instance));


Re: Using TYPE within an SQL IN statement [message #635211 is a reply to message #635209] Tue, 24 March 2015 13:16 Go to previous messageGo to next message
Duane
Messages: 557
Registered: December 2002
Senior Member
Ah, yes, easy to change. Looks like what I have won't work. Doing some reading. What I have is a PLSQL TYPE and not a SQL TYPE. I believe I need a SQL TYPE.

Going to try that.
Re: Using TYPE within an SQL IN statement [message #635212 is a reply to message #635211] Tue, 24 March 2015 13:22 Go to previous messageGo to next message
Duane
Messages: 557
Registered: December 2002
Senior Member
Looking good so far. It complied so now just to test.

SQL
create type instance_type as table of varchar2(50)

PLSQL

instance in (select * from table(Instances))

I used Instances.
Re: Using TYPE within an SQL IN statement [message #635213 is a reply to message #635212] Tue, 24 March 2015 13:28 Go to previous messageGo to next message
Michel Cadot
Messages: 68645
Registered: March 2007
Location: Nanterre, France, http://...
Senior Member
Account Moderator

Yes you need a SQL type (at least in 11g).

Re: Using TYPE within an SQL IN statement [message #635214 is a reply to message #635213] Tue, 24 March 2015 13:59 Go to previous messageGo to next message
Duane
Messages: 557
Registered: December 2002
Senior Member
It complied but I can't figure out how to use it. I'm sure this goes back to what you are saying. How do you pass in the input? Programming languages want to use varchar2, number, char..etc and the procedure is looking for a TYPE. Not sure how you pass anything to it to even use it.

I guess what I'm looking for is a way to pass in an array of values [oracle.world][peoplesoft.world][world.world] and the procedure says oh, ok, I'll put these into XYZ TYPE and you can query them out for your select statement.

That seems like such a simple task to do for PLSQL but it can't handle it. PLSQL: Oh, you're sending me an array of values from the web but I have no way to handle that data in some IN parameter TYPE. PLSQL: I can handle one value at a time just fine.
Re: Using TYPE within an SQL IN statement [message #635215 is a reply to message #635214] Tue, 24 March 2015 14:12 Go to previous messageGo to next message
Michel Cadot
Messages: 68645
Registered: March 2007
Location: Nanterre, France, http://...
Senior Member
Account Moderator

Programming language can also use the type but it is harder than a VARCHAR2, so you either have to study your programming language Oracle API or use a string and the usual CONNECT BY trick that I don't understand why you don't want to use and prefer to split the input string into an array (either in PL/SQL or in your programming language).

Re: Using TYPE within an SQL IN statement [message #635219 is a reply to message #635215] Tue, 24 March 2015 14:38 Go to previous messageGo to next message
Duane
Messages: 557
Registered: December 2002
Senior Member
It's because the data can contain a comma and the CONNECT BY is using the comma to separate out the values. Sure, we can use something else but then I'm sure the end user will use that in the data. Just seems like a bad way of parsing your data when it's possible a user could use that value.

It seemed like a way to get around the comma use and just pass in the actual values that could contain a comma.

If someone is actually using a Procedure with a TYPE as an INPUT I sure would like to see HOW they are calling it from the programming language. Had a developer try using .NET and he couldn't get it to work. Just seems like such a simple task but I'm sure PLSQL would have a hard time figuring out when the ARRAY started and ended and when any other IN parameter started and ended.
Re: Using TYPE within an SQL IN statement [message #635220 is a reply to message #635219] Tue, 24 March 2015 14:43 Go to previous messageGo to next message
Michel Cadot
Messages: 68645
Registered: March 2007
Location: Nanterre, France, http://...
Senior Member
Account Moderator

Quote:
Had a developer try using .NET and he couldn't get it to work.


So post this question (how to call a PL/SQL proceure with an array as input parameter from .Net, with your example) in our Windows forum.
The PL/SQL part is now over.

Re: Using TYPE within an SQL IN statement [message #635221 is a reply to message #635200] Tue, 24 March 2015 15:13 Go to previous messageGo to next message
Solomon Yakobson
Messages: 3273
Registered: January 2010
Location: Connecticut, USA
Senior Member
   open Results for
     select * 
       from outages
         where instance in (
                            select  instance
                              from  xmltable(
                                             'ora:tokenize($s,",")'
                                             passing INPUT as "s"
                                             columns
                                               instance varchar2(20) path '.'
                                            )
                           )


For example:

select  ename
  from  emp
  where ename in (
                  select  *
                    from  xmltable(
                                   'ora:tokenize($s,",")'
                                   passing 'KING,ALLEN,JONES' as "s"
                                   columns
                                     ename varchar2(20) path '.'
                                  )
                 )
/

ENAME
---------
KING
ALLEN
JONES

SQL> 


SY.
Re: Using TYPE within an SQL IN statement [message #635222 is a reply to message #635221] Tue, 24 March 2015 15:19 Go to previous messageGo to next message
Michel Cadot
Messages: 68645
Registered: March 2007
Location: Nanterre, France, http://...
Senior Member
Account Moderator

The problem is the same one:

Quote:
It's because the data can contain a comma and the CONNECT BY is using the comma to separate out the values.


Re: Using TYPE within an SQL IN statement [message #635237 is a reply to message #635222] Wed, 25 March 2015 07:21 Go to previous messageGo to next message
Solomon Yakobson
Messages: 3273
Registered: January 2010
Location: Connecticut, USA
Senior Member
Garbage in - garbage out. If OP decided to concatenate values using separator character that can be present in values then OP created garbage INPUT value.

SY.
Re: Using TYPE within an SQL IN statement [message #635245 is a reply to message #635237] Wed, 25 March 2015 08:49 Go to previous messageGo to next message
Michel Cadot
Messages: 68645
Registered: March 2007
Location: Nanterre, France, http://...
Senior Member
Account Moderator

I agree but this is why OP wants to fill an array with the values.
But I don't see why he does not use another character to separate the values.

Re: Using TYPE within an SQL IN statement [message #635246 is a reply to message #635245] Wed, 25 March 2015 08:57 Go to previous messageGo to next message
Duane
Messages: 557
Registered: December 2002
Senior Member
It's because the data being returned to us is comma-delimited but at times the data can contain a comma in it's internal data. Sure, we could use a different delimiter but what if the user uses that in the data. That's what I was trying to avoid.
Re: Using TYPE within an SQL IN statement [message #635273 is a reply to message #635246] Wed, 25 March 2015 16:03 Go to previous messageGo to next message
Bill B
Messages: 1971
Registered: December 2004
Senior Member
so use a separator that is not likely to be used like a vertical pipe or a tab

[Updated on: Wed, 25 March 2015 16:04]

Report message to a moderator

Re: Using TYPE within an SQL IN statement [message #635276 is a reply to message #635273] Thu, 26 March 2015 01:28 Go to previous message
Michel Cadot
Messages: 68645
Registered: March 2007
Location: Nanterre, France, http://...
Senior Member
Account Moderator

Or better chr(1) or chr(255)...

Previous Topic: request for solution
Next Topic: pl sql error
Goto Forum:
  


Current Time: Fri Apr 26 10:35:18 CDT 2024