2008-11-04 3 views
3

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

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

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

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

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

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

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

ответ

2

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

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

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

ВЫБОР s.hEmployee, e.sLastName
ОТ PR_Paystub сек
INNER JOIN PR_Employee е ON e.hKey = s.hEmployee
ГДЕ s.dtPaydate> '01/01/2008 '

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

1

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

Специальные правила преобразований применяются к типу Borland.Delphi.System.TDateTime объявленного в системном блоке. Когда Borland.Delphi.System.TDateTime - , преобразованный в любой другой тип, он рассматривается как обычный Double. Когда значение integer, real или Boolean преобразуется в Borland.Delphi.System.TDateTime, , оно сначала преобразуется в Double, , а затем считывается как значение даты. Когда строка преобразуется в 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; 
2

Хотя немного другой тип набора данных это то, что я использую с 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; 

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

2

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

for i := 0 to Qry.Params.Count - 1 do begin 
    Qry.Params[i].Clear; 
    Qry.Params[i].Bound := True; 
end; 
0
TmpQuery.ParamByName('MyDateTimeParam').DataType := ftDate; 
TmpQuery.ParamByName('MyDateTimeParam').Clear; 
TmpQuery.ParamByName('MyDateTimeParam').Bound := True; 
0

То, что я в конечном итоге делает это было:

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, но это было легко. Разделители - это просто символы, которые сигнализируют конец слова.

Смежные вопросы