Print Thread
Page 1 of 2 1 2
select with in-clause as parameter
#7289 04/06/05 04:17 PM
Joined: Feb 2004
Posts: 41
R
Ralf Offline OP
Member
OP Offline
Member
R
Joined: Feb 2004
Posts: 41
Hello,

I want to use a query like:

select * from table where id in (1,2,3)

but then with a parameter for the in-set.

select * from table where id in (:test)
or
select * from table where id in :test

how do i assign the variable?
can you give me a sample?
do i have to use a TOracleObject?

Re: select with in-clause as parameter
#7290 04/06/05 06:06 PM
Joined: Aug 2004
Posts: 83
Ukraine
A
Member
Offline
Member
A
Joined: Aug 2004
Posts: 83
Ukraine
Did you read Thomas Kyte
"Expert One-on-One Oracle",
Wrox Press Ltd&

Re: select with in-clause as parameter
#7291 04/06/05 06:12 PM
Joined: Aug 2004
Posts: 83
Ukraine
A
Member
Offline
Member
A
Joined: Aug 2004
Posts: 83
Ukraine
CREATE OR REPLACE
TYPE spis_integer AS OBJECT
(
ID NUMBER
)
/

CREATE OR REPLACE
TYPE Int_Table AS TABLE OF spis_integer
/


CREATE OR REPLACE FUNCTION Get_Spis_Integer(p_spis IN VARCHAR2)
RETURN Int_Table
DETERMINISTIC
AS

mytbl Int_Table := Int_Table();
i NUMBER;
j NUMBER;
k NUMBER;
k1 NUMBER;
k2 NUMBER;
v_spis_str VARCHAR2(100);
v_str VARCHAR2(100);
v_spis NUMBER;
v_error BOOLEAN;
iCount NUMBER;
maxCount NUMBER DEFAULT 100000;
BEGIN
IF p_spis IS NULL THEN
RETURN mytbl;
END IF;
i := 1;
iCount := 0;
LOOP
j := INSTR(p_spis, ',', i);
IF j = 0 THEN
j := INSTR(p_spis, ';', i);
END IF;
BEGIN
IF j > 0 THEN
v_spis_str := SUBSTR(p_spis, i, j-i);
ELSE
v_spis_str := SUBSTR(p_spis, i);
END IF;
EXCEPTION
WHEN OTHERS THEN
NULL;
END;
-- EXIT WHEN v_spis_str IS NULL;
k := INSTR(v_spis_str, '-', 1);
BEGIN
IF k > 0 THEN
k1 := trim(SUBSTR(v_spis_str, 1, k-1));
k2 := trim(SUBSTR(v_spis_str, k+1));
ELSE
k1 := v_spis_str;
k2 := k1;
END IF;
v_error := FALSE;
EXCEPTION
WHEN OTHERS THEN
v_error := TRUE;
DBMS_OUTPUT.put_line ('Error in (FUNCTION Get_Spis_Integer)' || CHR(13) ||
SQLERRM || CHR(13) || p_spis=' || p_spis);
END;
IF v_error = FALSE AND k1 IS NOT NULL THEN
k2 := NVL(k2, k1);
FOR k IN k1 .. k2 LOOP
mytbl.extend(1);
mytbl(mytbl.LAST):=spis_integer(k);
EXIT WHEN mytbl.LAST > maxCount;
END LOOP;
END IF;
iCount := iCount + 1;
i := j+1;
EXIT WHEN j = 0;
EXIT WHEN iCount > 100000;
END LOOP;

RETURN mytbl;
END;
/

SELECT * FROM the(SELECT cast(Get_Spis_Integer(:p_spis) AS Int_Table) FROM dual)

Re: select with in-clause as parameter
#7292 04/06/05 06:47 PM
Joined: Feb 2004
Posts: 41
R
Ralf Offline OP
Member
OP Offline
Member
R
Joined: Feb 2004
Posts: 41
i hope this can be done in another way.
this one is very slow.
i think it can be done with a TOracleObject, but i don't know how.

Re: select with in-clause as parameter
#7293 04/06/05 06:59 PM
Joined: Aug 2004
Posts: 83
Ukraine
A
Member
Offline
Member
A
Joined: Aug 2004
Posts: 83
Ukraine
And, Did you read Thomas Kyte ?

Re: select with in-clause as parameter
#7294 04/06/05 10:01 PM
Joined: Aug 1999
Posts: 22,221
Member
Offline
Member
Joined: Aug 1999
Posts: 22,221
[quote]I want to use a query like:

select * from table where id in (1,2,3)

but then with a parameter for the in-set.

select * from table where id in (:test)[/quote]In this case you can declare the :test variable as a substitution variable (otSubst), and assign "1,2,3" as a value (without the quotes). Substitution variable values are inserted into the SQL before it is sent to the server, so this should work properly.


Marco Kalter
Allround Automations
Re: select with in-clause as parameter
#7295 04/07/05 09:57 AM
Joined: Aug 2004
Posts: 83
Ukraine
A
Member
Offline
Member
A
Joined: Aug 2004
Posts: 83
Ukraine
"the substitution variable is replaced by its value in the SQL text before the statement is sent to the server"
We will get new SQL text after every setVariable.
As for me, It's not good idea.

Re: select with in-clause as parameter
#7296 04/07/05 12:02 PM
Joined: Feb 2004
Posts: 41
R
Ralf Offline OP
Member
OP Offline
Member
R
Joined: Feb 2004
Posts: 41
The target is to speed up queries.
Previously we replaced markers in the SQL on the client side. So every query has to be evaluated by Oracle (explain plan etc). Therefor we want to use as much parameters as possible, making it possible for oracle to use the same explain plan.
The suggestion by Andrey is more than 2 times slower than putting the arguments directly in the SQL clientside.
Does the substitution variable make it possible for oracle to use the same explain-plan (sounds like it does not)?

PS : I didn't read Thomas Kyte...

Re: select with in-clause as parameter
#7297 04/07/05 07:24 PM
Joined: Aug 1999
Posts: 22,221
Member
Offline
Member
Joined: Aug 1999
Posts: 22,221
[quote]Does the substitution variable make it possible for oracle to use the same explain-plan (sounds like it does not)?[/quote]No, but the cost based optimizer may be able to come up with optimized query plans for different sets of id's. Which option is faster depends on many factors.


Marco Kalter
Allround Automations
Re: select with in-clause as parameter
#7298 04/08/05 03:57 PM
Joined: Feb 2004
Posts: 41
R
Ralf Offline OP
Member
OP Offline
Member
R
Joined: Feb 2004
Posts: 41
But if I want to do this with a parameter.
A table-parameter of something like that (not a string/function combination).
Is that possible or not?

Re: select with in-clause as parameter
#7299 04/08/05 06:07 PM
Joined: Feb 2004
Posts: 41
R
Ralf Offline OP
Member
OP Offline
Member
R
Joined: Feb 2004
Posts: 41
So I want an equivalent in Delphi of the following in PL/SQL:

create or replace function table_select_test
return integer
is
lvDeleted myTableType := myTableType(0, 1);
lvCount integer;
begin
select count(*)
into lvCount
from receiver
where deleted in (select * from table(table_select_test.lvDeleted));
return lvCount;
end;
/

Re: select with in-clause as parameter
#7300 04/08/05 07:50 PM
Joined: Aug 1999
Posts: 22,221
Member
Offline
Member
Joined: Aug 1999
Posts: 22,221
It might work like this (haven't tried it!!):
Code
begin
  select count(*)
    into :lvCount
    from receiver
   where deleted in (select * from table(cast :lvDeleted as myTableType));
end;
The :lvDeleted variable is associated with a collection that is instantiated and filled in Delphi.


Marco Kalter
Allround Automations
Re: select with in-clause as parameter
#7301 04/11/05 10:56 AM
Joined: Feb 2004
Posts: 41
R
Ralf Offline OP
Member
OP Offline
Member
R
Joined: Feb 2004
Posts: 41
And how does my delphi-code look like???

Re: select with in-clause as parameter
#7302 04/11/05 09:33 PM
Joined: Aug 1999
Posts: 22,221
Member
Offline
Member
Joined: Aug 1999
Posts: 22,221
That depends. What does your myTableType look like?


Marco Kalter
Allround Automations
Re: select with in-clause as parameter
#7303 04/12/05 11:19 AM
Joined: Feb 2004
Posts: 41
R
Ralf Offline OP
Member
OP Offline
Member
R
Joined: Feb 2004
Posts: 41
myTableType looks like whatever is going to work!
I don't care what type it is.
Maybe my problem isn't clear...

I want to use a TOracleDataset in which I put SQL that contains an in-struct and in which the in-part is a variable. So something like:

'select * from table where id in (:test)'

Runtime I assign a list of integers to the variable 'test' and execute the query.
So I want to use variables all the way to Oracle (no substitution etc.).
How do I do this in Delphi and what types do I need in Oracle? How does the query look like?
Can you provide me a full example?

Thanks in advance.

Re: select with in-clause as parameter
#7304 04/12/05 09:12 PM
Joined: Aug 1999
Posts: 22,221
Member
Offline
Member
Joined: Aug 1999
Posts: 22,221
I will try to work something out.


Marco Kalter
Allround Automations
Re: select with in-clause as parameter
#7305 04/13/05 07:03 PM
Joined: Mar 2005
Posts: 14
Russian
W
Member
Offline
Member
W
Joined: Mar 2005
Posts: 14
Russian
May be the following example help you...
Code
In Oracle:
--Is Number in set?
create or replace type TNumbers as table of number(9);
/
create or replace function Value_In(p_Value in number, p_Set in TNumbers) return number is
  v_Result number(1) := 0;
begin
  begin
    select 1 into v_Result from dual
      where p_Value in (select * from table(p_Set));
  exception
    when NO_DATA_FOUND then null;
  end;
  return v_Result;
end;
/
//
In Delphi the PL/SQL block for TOracleDataSet component SQL property:
select * from yourtable t where Value_In(:v_ID, :v_Set) = 1;
Though you need to bind value to variables v_ID and v_Set.
To bind value to v_Set you need to use the followning code:
...
var
  v_Set: TOracleObject;
...
begin
...
  v_Set := TOracleObject.Create(orcSession, 'TNUmbers', '');
...
  v_Set.Elements[1] := 1;
  v_Set.Elements[2] := 2;
...
  orcYourTable.SetVariable('v_ID', 1);
  orcYourTable.SetComplexVariable('v_Set', v_Set);
...
end;
// :)
You can test the function with the following code in "Test window"(PL/SQL Developer):
Code
declare
  r number(1) := Value_In(:v_ID, :v_Set);
begin
  dbms_output.put_line(r);
end;
with the following initialization values:
Test1:
  v_ID = "1";
  v_Set = "new TNumbers(1, 2, 3)";
  Tab sheet "DBMS Output" contain "1" as a result.
Test2:
  v_ID = "1";
  v_Set = "new TNumbers(2, 3)";
  Tab sheet "DBMS Output" contain "0" as a result.

Re: select with in-clause as parameter
#7306 04/14/05 01:49 PM
Joined: Feb 2004
Posts: 41
R
Ralf Offline OP
Member
OP Offline
Member
R
Joined: Feb 2004
Posts: 41
Ooops...

Read following post.

Re: select with in-clause as parameter
#7307 04/14/05 02:36 PM
Joined: Feb 2004
Posts: 41
R
Ralf Offline OP
Member
OP Offline
Member
R
Joined: Feb 2004
Posts: 41
Sorry, made a mistake in my test program.
Now it works great!

Thanks Worad for the example!

Page 1 of 2 1 2

Moderated by  support 

Link Copied to Clipboard
Powered by UBB.threads™ PHP Forum Software 7.7.4
(Release build 20200307)
Responsive Width:

PHP: 7.1.33 Page Time: 0.053s Queries: 13 (0.009s) Memory: 2.6064 MB (Peak: 3.0438 MB) Data Comp: Off Server Time: 2024-05-20 17:54:40 UTC
Valid HTML 5 and Valid CSS