我有一个带有SQL定义的TOraQuery
SELECT ML.ID, Ml.detail1, Ml.detail2
FROM MY_LIST ML
WHERE
ML.ID in (:My_IDS)
如果我要动态构建这个查询,我自然会得到这样的结果:
SELECT ML.ID, Ml.detail1, Ml.detail2
FROM MY_LIST ML
WHERE
ML.ID in (14001,14002,14003)
但是,我想传递14001,14002,14003
作为参数。
myListQuery.Active := False;
myListQuery.ParamByName('My_IDS').AsString := '14001,14002,14003';
myListQuery.Active := True;
但当然会产生ORA-01722: invalid number
。除了快速构建查询之外,我还有其他选择。
答案 0 :(得分:1)
AFAIK,直接无法实现。
您必须将列表转换为纯文本的SQL列表。
例如:
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;
如此使用:
SQL.Text := 'select * from myTable where intKey in '+ListToText([1,2,3]);
SQL.Text := 'select * from myTable where stringKey in '+ListToText(['a','b','c']);
或者在你的情况下:
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]);
答案 1 :(得分:1)
您可以这样做,但需要一些额外的设置。希望这适用于您的Oracle版本。
在子查询中使用CAST。使用您在代码中使用的相同内容将值传递给绑定变量(即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
如果这对您有用,那么答案和示例代码的功劳归于运行asktom.com的Oracle的Tom Kyte。 https://asktom.oracle.com/pls/asktom/f?p=100:11:0%3a%3a%3a%3aP11_QUESTION_ID:210612357425
答案 2 :(得分:0)
您可以使用"宏"
不是我想要的,但是它比参与动态构建SQL更接近参数。
像这样创建TOraQuery
SELECT ML.ID, Ml.detail1, Ml.detail2
FROM MY_LIST ML
WHERE
ML.ID in (&My_IDS)
现在我可以将14001,14002,14003
作为宏传递。
myListQuery.Active := False;
myListQuery.MacroByName('My_IDS').value := '14001,14002,14003';
myListQuery.Active := True;