Передать параметр "в" Delphi

Мне нужно передать параметр в SQL в Delphi, используя BDE, чтобы использовать "in", пример ниже:

select * from customers where id in (:p_in)

Мне нужно передать: p_in список клиентов. Но Query.ParamByName.('p_in').AsString: = '1, 2,3 ', и это не сработало.. Придется делать массив? или переданный AsVariant?

3 ответа

Решение

Попробуй это:

p_in  : String ;

for i := 0 to Customerlist.count do
   p_in := p_in +Customerlist[i] + ','; 

MyQuery.text := 'select * from customers where id in (' + p_in  + ' )' ;

Вы должны построить свой SQL динамически. (См. Вторую половину моего ответа, хотя.)

var
  SQLStr: string;
  i: Integer;
begin
  SQLStr := 'SELECT * FROM Customers WHERE id IN (';
  for i := 0 to CustomerList.Count - 1 do
    SQLStr := SQLStr + QuotedStr(CustomerList[i]) + ',';
  // Replace final extra comma with closing ')'
  SQLStr[Length(SQLStr)] := ')';
  MyQuery.SQL.Text := SQLStr;
  ...
end;

Обратите внимание, что для предотвращения внедрения SQL вы должны сделать это с параметризованным SQL, хотя это требует больше работы. Это также будет работать и будет более безопасным:

var
  SQLStr: string;
  i: Integer;
begin
  SQLStr := 'SELECT * FROM Customers WHERE id IN (';

  // Add parameters to hold values like `:ID`
  for i := 0 to CustomerList.Count - 1 do
    SQLStr := SQLStr + Format(':ID%d,' [i]);

  // Remove final extra comma and replace with closing ')', and
  // then assign it to MyQry.SQL; the query will parse the params
  if CustomerList.Empty then
    SQLStr := SQLStr + ')'
  else
    SQLStr[Length(SQLStr)] := ')';
  MyQuery.SQL.Text := SQLStr;

  // Populate the parameters
  for i := 0 to CustomerList.Count - 1 do
    MyQuery.ParamByName(Format('ID%d', [i])).AsString := CustomerList[i];

  // Execute query
  MyQuery.Open;
end;

Вы также можете напрямую заменить их, если у вас нет других параметров в SQL, но прямой доступ к ним по индексу может вызвать проблемы, если вы позже измените запрос и добавите новый параметр! Просто замени второй for цикл с этим вместо этого:

for i := 0 to CustomerList.Count - 1 do
  MyQuery.Params[i].AsString := CustomerList[i];

Поскольку BDE устарел, рассмотрите возможность использования современных компонентов, которые позволяют заменять параметры. Пример:

SomeDataSet.SQL.Add('select foo from bar where baz in (:TESTIDS)');
SomeDataSet.DeclareVariable('TESTIDS', otSubst);  // <- this does the trick
// Place here some loop that fills the list of test-id separated by a ","
// And then:
SomeDataSet.SetVariable('TESTIDS', myIDList);  // Drop the list into the variable

Для этого разные производители компонентов могут использовать разные названия.

Другие вопросы по тегам