4

プログラムのユーザーが実行時に定義したクエリからフィールドのリストを取得する際に問題があります。ユーザーが SQL クエリをメモ コントロールに入力できるようにしてから、返されるフィールドを通過させ、出力の書式設定、列の値の合計などを実行させたいと考えています。そのため、列名を取得して、追加情報を入力する場所を確保する必要があります。

パラメーターがなくても問題ありませんが、クエリのフィルター パラメーターを定義させる必要もあります。したがって、パラメーターを null に設定したい場合は、パラメーターのデータ型が何であるかを知る必要があります。

Delphi 2006 を使用しています。DBExpress コンポーネントの TSQLConnection と TSQLQuery を使用して、Firebird 2.1 データベースに接続しています。以前は、次を使用して成功していました。

for i := 0 to Qry.Params.Count - 1 do Qry.Params[i].value := varNull;

日付パラメーターを使用しようとしたときに問題があることがわかりました。それまでのパラメータはすべて整数(レコード ID)だったのは偶然でした。varNull は値が 1 の列挙定数にすぎないことが判明したため、許容できる結果 (レコードなし) が正常に機能していました。

フィールドのリストだけが必要です。おそらく、SQL ステートメントの SELECT 句を解析する必要があります。Qry.Prepared を True に設定すると、フィールドのリストが表示されると思いましたが、そのような運はありませんでした。パラメータの値が必要です。

アイデアがあれば、ぜひお聞きしたいです。助けてくれてありがとう。

4

6 に答える 6

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;   

終わり;
クエリで同様のことを行うことはできませんか?

于 2008-11-04T10:01:31.147 に答える
2

あなたたちはこの方法を難しくしすぎています:

for i := 0 to Qry.Params.Count - 1 do begin
    Qry.Params[i].Clear;
    Qry.Params[i].Bound := True;
end;
于 2008-11-04T13:19:17.083 に答える
2

興味があるのでもう一度返信しました。私のメソッドは、正しいタイプにプリセットされたパラメーターのデータ型で事前定義されているため、(私のクエリで) 機能します:)

操作対象のフィールドを選択していない場合、クエリがパラメーターのデータ型をどのように認識または導出することを期待しているのかわかりません。

したがって、クエリの設定とユーザー入力方法にはさらに注意が必要だと思います。少し前にこれをどのように行ったかを調べました。パラメータ化されたクエリは使用しません。ユーザーから「パラメータ値」を取得し、SQL に直接入力するだけです。したがって、SQLは次のようになります。

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

したがって、パラメータ タイプの知識は必要ありません。ユーザーがゴミを入力するのを止めませんが、それは入力制御に戻ります:)

于 2008-11-05T14:43:15.853 に答える
1

私がやったことはこれでした:

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 を書かなければなりませんでしたが、それは簡単でした。区切り文字は、単語の終わりを示す単なる文字です。

于 2008-11-26T20:40:23.277 に答える
1

使用している Delphi のバージョンがわかりません。バリアント型の下の Delphi 2006 ヘルプでは、次のように述べています。

System ユニットで宣言された Borland.Delphi.System.TDateTime 型には、特別な変換規則が適用されます。Borland.Delphi.System.TDateTime が他の型に変換されると、通常の Double として扱われます。整数、実数、またはブール値が Borland.Delphi.System.TDateTime に変換される場合、まず Double に変換され、次に日時値として読み取られます。文字列が Borland.Delphi.System.TDateTime に変換されると、地域設定を使用して日時値として解釈されます。Unassigned 値が Borland.Delphi.System.TDateTime に変換されると、実数または整数値 0 のように扱われます。Null 値を 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;
于 2008-11-04T01:49:52.670 に答える
0
TmpQuery.ParamByName('MyDateTimeParam').DataType := ftDate;
TmpQuery.ParamByName('MyDateTimeParam').Clear;
TmpQuery.ParamByName('MyDateTimeParam').Bound := True;
于 2008-11-26T13:13:50.637 に答える