Reputation: 15414
I have a TOraQuery with SQL defined something like this
SELECT ML.ID, Ml.detail1, Ml.detail2
FROM MY_LIST ML
WHERE
ML.ID in (:My_IDS)
If I was to build this query on the fly, I'd naturally end up with something like this:
SELECT ML.ID, Ml.detail1, Ml.detail2
FROM MY_LIST ML
WHERE
ML.ID in (14001,14002,14003)
However, I'd like to pass in 14001,14002,14003
as a parameter.
myListQuery.Active := False;
myListQuery.ParamByName('My_IDS').AsString := '14001,14002,14003';
myListQuery.Active := True;
But of course that generates an ORA-01722: invalid number
. Do I have any other option other than building up the query on the fly.
Upvotes: 1
Views: 2347
Reputation: 15414
You can use a "Macro"
Not quite what I was looking for, but it's a hair closer to a parameter than building the SQL on the fly.
Create the TOraQuery like this
SELECT ML.ID, Ml.detail1, Ml.detail2
FROM MY_LIST ML
WHERE
ML.ID in (&My_IDS)
Now I can pass in 14001,14002,14003
as a macro.
myListQuery.Active := False;
myListQuery.MacroByName('My_IDS').value := '14001,14002,14003';
myListQuery.Active := True;
Upvotes: 0
Reputation: 4166
You can do it but it requires some additional setup. Hopefully this works with your version of Oracle.
Use CAST in the subquery. Pass your value to the bind variable using the same thing you have in your code (i.e. ParamByName('').AsString).
create or replace type myTableType as table of varchar2 (255);
create or replace function in_list( p_string in varchar2 ) return myTableType as
l_string long default p_string || ',';
l_data myTableType := myTableType();
n number;
begin
loop
exit when l_string is null;
n := instr( l_string, ',' );
l_data.extend;
l_data(l_data.count) :=
ltrim( rtrim( substr( l_string, 1, n-1 ) ) );
l_string := substr( l_string, n+1 );
end loop;
return l_data;
end;
select * from THE ( select cast( in_list(:MY_BIND_VARIABLE) as mytableType ) from dual ) a
If this works for you, credit for the answer and example code goes to Tom Kyte from Oracle who runs asktom.com. https://asktom.oracle.com/pls/asktom/f?p=100:11:0%3a%3a%3a%3aP11_QUESTION_ID:210612357425
Upvotes: 1
Reputation: 6402
AFAIK, it is not possible directly.
You'll have to convert the list into a SQL list in plain text.
For instance:
function ListToText(const Args: array of string): string; overload;
var
i: integer;
begin
result := '(';
for i := 0 to high(Args) do
result := result+QuotedStr(Args[i])+',';
result[length(result)] := ')';
end;
function ListToText(const Args: array of integer): string; overload;
var
i: integer;
begin
result := '(';
for i := 0 to high(Args) do
result := result+IntToStr(Args[i])+',';
result[length(result)] := ')';
end;
To be used as such:
SQL.Text := 'select * from myTable where intKey in '+ListToText([1,2,3]);
SQL.Text := 'select * from myTable where stringKey in '+ListToText(['a','b','c']);
Or in your case:
myListQuery.SQL.Text := 'SELECT ML.ID, Ml.detail1, Ml.detail);
myListQuery.SQL.Add('FROM MY_LIST ML ');
myListQuery.SQL.Add('WHERE ');
myListQuery.SQL.Add('ML.ID in ') + ListToText([14001,14002,14003]);
Upvotes: 1