如何将值列表作为TOraQuery的参数传递?

时间:2015-05-04 20:06:37

标签: delphi delphi-xe7

我有一个带有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。除了快速构建查询之外,我还有其他选择。

3 个答案:

答案 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版本。

  1. 创建表格类型
  2. 创建一个将字符串转换为表格类型的函数
  3. 在子查询中使用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
    
  4. 如果这对您有用,那么答案和示例代码的功劳归于运行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;