Получение списка полей из DBExpress TSQLQuery - PullRequest
3 голосов
/ 04 ноября 2008

У меня проблема с получением списка полей из запроса, определенного во время выполнения пользователями моей программы. Я позволил своим пользователям вводить SQL-запрос в элемент управления memo, а затем я хочу позволить им пройти через поля, которые будут возвращаться, и выполнять такие операции, как форматирование вывода, значения столбцов суммы и так далее. Поэтому мне нужно получить имена столбцов, чтобы у них было место для ввода дополнительной информации.

Я бы хорошо, если бы не было параметров, но я также должен позволить им определить параметры фильтра для запроса. Итак, если я хочу установить для параметров значение null, я должен знать, каков тип данных параметра.

Я использую Delphi 2006. Я подключаюсь к базе данных Firebird 2.1, используя компоненты DBExpress TSQLConnection и TSQLQuery. Ранее я успешно использовал:

для i: = 0 до Qry.Params.Count - 1 до Qry.Params [i] .value: = varNull;

Я обнаружил, что у меня возникла проблема при попытке использовать параметр даты. Это было просто совпадение, что все мои параметры до этого были целыми числами (идентификаторы записей). Оказывается, что varNull - это просто перечисляемая константа со значением 1, поэтому я получаю приемлемые результаты (без записей), все в порядке.

Мне нужен только список полей. Может быть, я должен просто разобрать предложение SELECT оператора SQL. Я думал, что установка Qry.Prepared в True даст мне список полей, но не повезло. Он хочет значения для параметров.

Если у вас есть идея, я бы очень хотел ее услышать. Спасибо за любую помощь.

Ответы [ 6 ]

2 голосов
/ 05 ноября 2008

Ответил снова, потому что я заинтересован. Мои методы работают (с моими запросами), потому что они были предварительно определены с типом данных params, установленным на правильный тип:)

Я не уверен, как вы ожидаете, что запрос узнает или получит тип данных параметра, учитывая, что вы даже не выбираете поле, с которым он работает.

Так что я думаю, что настройка вашего запроса и метод пользовательского ввода потребуют большего внимания. Я только что посмотрел, как я это сделал некоторое время назад. Я не использую параметризованный запрос - я просто получаю «значения параметров» от пользователя и помещаю их непосредственно в SQL. Таким образом, ваш sql будет читать:

SELECT s.hEmployee, e.sLastName
FROM PR_Paystub s
INNER JOIN PR_Employee e ON e.hKey = s.hEmployee
ГДЕ s.dtPaydate> '01 / 01/2008 '

поэтому знание типа параметра не требуется. Не мешает вашим пользователям вводить мусор, но это возвращает к управлению вводом:)

2 голосов
/ 04 ноября 2008

Вы, ребята, делаете этот путь слишком сложным:

for i := 0 to Qry.Params.Count - 1 do begin
    Qry.Params[i].Clear;
    Qry.Params[i].Bound := True;
end;
2 голосов
/ 04 ноября 2008

Хотя немного другой тип набора данных, это то, что я использую с TClientDataset просто и эффективно:)

for i := 0 to FilterDataSet.Params.Count -1 do  
begin  
 Case FilterDataSet.Params.Items[i].Datatype of  
    ftString:  
    ftSmallint, ftInteger, ftWord:  
    ftFloat, ftCurrency, ftBCD:  
    ftDate:  
    ftTime:  
    ftDateTime:  
    .  
    .  
    . 
end;   

конец;
Вы не можете сделать что-то подобное с запросом?

1 голос
/ 04 ноября 2008

Я не уверен, какую версию Delphi вы используете. В справке по Delphi 2006 в разделе Типы вариантов указано:

Специальные правила преобразования применяются к Borland.Delphi.System.TDateTime type заявлено в Системном блоке. Когда Borland.Delphi.System.TDateTime is преобразован в любой другой тип, это трактуется как обычный дубль. Когда целое, вещественное или логическое значение Borland.Delphi.System.TDateTime, сначала он конвертируется в двойной, затем читать как значение даты и времени. Когда строка преобразуется в Borland.Delphi.System.TDateTime, это интерпретируется как значение даты и времени с использованием региональные настройки. Когда Неназначенное значение преобразуется в Borland.Delphi.System.TDateTime, это рассматривается как действительное или целочисленное значение 0. Преобразование нулевого значения в Borland.Delphi.System.TDateTime повышает исключение.

Последнее предложение кажется мне важным. Я бы прочитал это, поскольку varNull нельзя преобразовать в TDateTime для помещения в поле, и, следовательно, вы получите исключение, которое вы испытываете.

Это также означает, что это единственный особый случай.

Не могли бы вы сделать что-то вроде:

for i := 0 to Qry.Params.Count - 1 do 
begin
  if VarType(Qry.Params[i].value) and varTypeMask = varDate then
  begin
    Qry.Params[i].value := Now; //or whatever you choose as your default
  end
  else
  begin
    Qry.Params[i].value := varNull;
  end;
end;
0 голосов
/ 26 ноября 2008

Я закончил тем, что сделал:

sNull := 'NULL';
Qry.SQL.Add(sSQL);
for i := 0 to Qry.Params.Count - 1 do begin
  sParamName := Qry.Params[i].Name;
  sSQL := SearchAndReplace (sSQL, ':' + sParamName, sNull, DELIMITERS);
end;

Мне пришлось написать SearchAndReplace, но это было легко. Разделители - это просто символы, обозначающие конец слова.

0 голосов
/ 26 ноября 2008
TmpQuery.ParamByName('MyDateTimeParam').DataType := ftDate;
TmpQuery.ParamByName('MyDateTimeParam').Clear;
TmpQuery.ParamByName('MyDateTimeParam').Bound := True;
...