クエリーで日付型項目を空値にするには

解決


hebo  2012-10-30 00:54:33  No: 43273

Windows7上でDelphiXE2を使用しています。
ローカルのDBとしてParadox形式のテーブルを使用していて日付型の項目を
空値にするためにクエリーで処理しようとして、paramにAssign(nil)を
渡してみたんですが、クエリーだと駄目みたいなんですがなにか方法が
有りますでしょうか。ネットも調べましたが中々良い答えが見つかりません
ので、教えてください。


初心者  2012-10-30 02:27:25  No: 43274

パラメータを空白なら文字列にして''で送ればいいのじゃないの??
どんなクエリなのでしょうか?


au  2012-10-30 02:33:06  No: 43275

ParameterのIsNULLプロパティをTrueに設定すれば良かったと思います


hebo  2012-10-30 02:41:10  No: 43276

話が見えなかったようですみません。

以下のコードを書いてみましたが、思うような結果になりません。

    Query3.Close;
    with Query3 do
    begin
        SQL.Clear;
        SQL.Add('UPDATE "発注.DB"');
        SQL.Add('SET 回答納期 = :P1, 備考 = :P2');
        SQL.Add('WHERE (購買伝票番号 = :P3)');
        SQL.Add(' AND (明細番号 = :P4)');
        if HatyuTbl.FieldByName('回答納期').AsDateTime < now - 300  then
            params[0].asDateTime := 0  {.Assign(Nil)アサインはエラー}
        else
          params[0].AsDateTime := HatyuTbl.FieldByName('回答納期').asDateTime;
        params[1].AsString := HatyuTbl.FieldByName('備考').asString;
        params[2].AsString := HatyuTbl.Fields[0].AsString;
        params[3].AsString := HatyuTbl.Fields[1].AsString;
        try
            execSQL;
        except
            showMessage('更新に失敗しました!');
        end;
        showMessage('変更を保存しました!');

    end;

入力しているローカルテーブルで日付項目を訂正時に削除した場合、空白になりますがこの変更をサーバー上のテーブルに反映させるために、
クエリーでサーバーに書き戻したいのですが、日付型項目を空白にするSQLの書き方が分らないです。ポインターでアサインしてあげれば出来るんですけど
できればクエリーで処理できないかと思って質問しました。

よろしくお願いします。


hebo  2012-10-30 02:49:02  No: 43277

auさん、お返事ありがとうございます。

isNullプロパティて有りましたっけ。
ちょっと分らないです。

ちなみに0を代入すると1890年に確かなってしまうので空白にしたいのです。


Quest  2012-10-30 08:47:05  No: 43278

params[0].Clear;
ってのはどう?
もしかしたら
params[0].FieldType := ftDateTime; //ちょい、うろ覚え
をClearの前に入れる必要があるかも。


au  2012-10-30 17:44:49  No: 43279

Clearの呼び出しだけだと値が設定されていないと判断される気がするので、以下みたいな感じでよいのではないかと。

Params[0].Clear;
Params[0].Bound := True;
Params[0].IsNull := True;

ttp://docwiki.embarcadero.com/Libraries/XE2/ja/Data.DB.TParam.IsNull
ttp://docwiki.embarcadero.com/Libraries/XE2/ja/Data.DB.TParam.Bound


初心者  2012-10-30 17:52:42  No: 43280

Query3.Close;
    with Query3 do
    begin
        SQL.Clear;
        SQL.Add('UPDATE "発注.DB"');
        if HatyuTbl.FieldByName('回答納期').AsDateTime < now - 300  then
        begin
          SQL.Add('SET 回答納期 = '', 備考 = :P1');
          SQL.Add('WHERE (購買伝票番号 = :P2)');
          SQL.Add(' AND (明細番号 = :P3)');
          Params.ParamByName('P1').AsString := HatyuTbl.FieldByName('備考').asString;
          Params.ParamByName('P2').AsString := HatyuTbl.Fields[0].AsString;
          Params.ParamByName('P3').AsString := HatyuTbl.Fields[1].AsString;          
        end  
        else
        begin
          SQL.Add('SET 回答納期 = :P1, 備考 = :P2');
          SQL.Add('WHERE (購買伝票番号 = :P3)');
          SQL.Add(' AND (明細番号 = :P4)');
          Params.ParamByName('P1').AsString := HatyuTbl.FieldByName('回答納期').asDateTime;
          Params.ParamByName('P2').AsString  := HatyuTbl.FieldByName('備考').asString;
          Params.ParamByName('P3').AsString := HatyuTbl.Fields[0].AsString;
          Params.ParamByName('P4').AsString := HatyuTbl.Fields[1].AsString;             
        end;
        try
          execSQL;
        except
          showMessage('更新に失敗しました!');
        end;
        showMessage('変更を保存しました!');

    end;

こんな書き方ってできましたっけ?


hebo  2012-10-30 18:45:55  No: 43281

うわ、一気に書き込みが。(^^;)
皆さん、ありがとうございます。

教わりました方法、確認してみます。
確認したら、またご報告いたします。


hebo  2012-10-30 20:57:49  No: 43282

皆さんのご指摘に従い確認しました。
まず、Questさんとauさんのご指摘方法で試しました。

    Query3.Close;
    with Query3 do
    begin
        SQL.Clear;
        SQL.Add('UPDATE "発注.DB"');
        SQL.Add('SET 回答納期 = :P1, 備考 = :P2');
        SQL.Add('WHERE (購買伝票番号 = :P3)');
        SQL.Add(' AND (明細番号 = :P4)');
        if HatyuTbl.FieldByName('回答納期').IsNull then
          begin
                params[0].clear;
                params[0].Bound := True;
            end
        else
          params[0].AsDateTime := HatyuTbl.FieldByName('回答納期').asDateTime;
          params[0].AsString := HatyuTbl.FieldByName('備考').asString;
          params[1].AsString := HatyuTbl.Fields[0].AsString;
          params[2].AsString := HatyuTbl.Fields[1].AsString;
        try
          execSQL;
        except
            showMessage('サーバーの更新に失敗しました!');
            exit;
        end;
        showMessage('変更を保存しました!');

    end;

実行したら、"項目P1は不明なタイプです"というエラーメッセージで止まってしまいました。
ちなみに、params[0].FieldType := ftDateTime  のFieldTypeはプロパティに無いみたいです。

初心者さんの例も試しましたが、更新できませんでした。


DEKO  2012-10-30 23:07:36  No: 43283

こんにちは。

  Params[0].Value := System.Variants.NULL;
  Params[0].DataType := ftString; // 文字列型等の場合にはパラメータの型を明示的に指定

こんな感じでよかったと思います。


DEKO  2012-10-30 23:13:48  No: 43284

失礼しました、日付型ですね。

  Params[0].Value := System.Variants.NULL;
  Params[0].DataType := ftDateTime;


hebo  2012-10-30 23:28:31  No: 43285

DEKOさん、ありがとうございます。
  DEKOさんにはIBConsole等でいつもお世話になっております。()(。。)ペコッ

仰せの通り、出来ました〜。

それからQuestさんとauさんのご指摘に有った方法でも、FieldTypeをDataTypeにしたら問題なく動作しました。

        if HatyuTbl.FieldByName('回答納期').IsNull then
          begin
              //Params[0].Value := System.Variants.NULL;
                params[0].clear;
                params[0].Bound := True;
                Params[0].DataType := ftDate;  // これがキモみたい
            end

  DEKOさんとQuestさん・auさんの両方確認してみました。

どちらにしろ、皆さんのお陰でなんとかなりましたし、知らなかったプロパティも教えていただいて、本当にありがとうございました。
また、なにか有りましたら宜しくお願いいたします。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加