複数項目をSQL文でParamByNameを使って更新するするには?

解決


もも  2009-07-22 02:00:26  No: 35184

いつもお世話になります。
  複数項目をSQL文で更新するコーディングをしています。
  エラーは出ないのですが、データが更新されません。
  ここには書いていませんが、以前ご教授頂いたときは項目が1つの場合で
上手く更新・削除・追加が出来ました。
  同じようにコーディングしたつもりなのですが、複数項目になると動作しません。
  どこか間違っていますのでしょうか?
  どなたかご教授頂けますでしょうか?
--------------------------------------------------------------------------------
ADOQuery1.Close;
ADOQuery1.SQL.Clear;
ADOQuery1.SQL.Add('UPDATE Name_Table');
ADOQuery1.SQL.Add('SET ');
ADOQuery1.SQL.Add('区分名称         = :_区分名称,');
ADOQuery1.SQL.Add('名称№           = :_名称№,');
ADOQuery1.SQL.Add('名称(ふりがな) = :_名称(ふりがな),');
ADOQuery1.SQL.Add('名称(漢字)     = :_名称(漢字),');
ADOQuery1.SQL.Add('名称(略称)     = :_名称(略称),');
ADOQuery1.SQL.Add('備考             = :_備考');
ADOQuery1.SQL.Add('WHERE ');
ADOQuery1.SQL.Add('名称区分         = :_名称区分');
ADOQuery1.SQL.Add('AND');
ADOQuery1.SQL.Add('名称№           = :_名称№');
ADOQuery1.Parameters.ParamByName('_区分名称').Value := Null;
ADOQuery1.Parameters.ParamByName('_名称(ふりがな)').Value := Form2.Edit4.Text;
ADOQuery1.Parameters.ParamByName('_名称(漢字)').Value := Form2.Edit5.Text;
ADOQuery1.Parameters.ParamByName('_名称(略称)').Value := Form2.Edit6.Text;
ADOQuery1.Parameters.ParamByName('_備考').Value         := Form2.Memo2.Text;
ADOQuery1.Parameters.ParamByName('_名称区分').Value     := g2_int_wk;
ADOQuery1.Parameters.ParamByName('_名称№').Value := StrToInt(Form2.Edit3.Text);
ADOQuery1.ExecSQL;
--------------------------------------------------------------------------------


igy  2009-07-22 09:21:04  No: 35185

ADOQueryのSQL文のWHERE句に変数は使えないのでしょうか?
https://www.petitmonte.com/bbs/answers?question_id=6427

で、オラクル勉強者 さん が
>2009/07/13(月) 18:30:01 
で書かれたように、

>ADOQuery1.Parameters.ParamByName(バインド変数).タイプ := セットする値

は指定していますか?


もも  2009-07-22 17:52:45  No: 35186

ParamByName(バインド変数).タイプですが、.タイプは
.ValueしかVCLでは選択できません。VCLの補完機能を無視
して直接『.Integer』とかを入力しないといけませんか?


もも  2009-07-22 17:54:16  No: 35187

『.Integer』→『.AsInteger』のタイプミスです。


igy  2009-07-22 18:17:07  No: 35188

ADOQuery1.Parameters.ParamByName('_名称№').DataType := ftInteger;

のような感じで、どうでしょう?


oracle勉強中  2009-07-22 18:56:17  No: 35189

例に出されているSQLは、サンプルでしょうか?
もしも、このSQLをそのまま実行している場合は、SQLエラーで落ちていると思われます。

例えば
>ADOQuery1.SQL.Add('UPDATE Name_Table');
>ADOQuery1.SQL.Add('SET ');
>ADOQuery1.SQL.Add('区分名称         = :_区分名称,');

このSQLは
「UPDATE Name_TableSET 区分名称         = :_区分名称,」
となってしまい、テーブル名とSETがくっついた状態になってしまいます。
まずは、ここから確認してください。

>ParamByName(バインド変数).タイプですが、.タイプは.ValueしかVCLでは選択できません。
>VCLの補完機能を無視して直接『.Integer』とかを入力しないといけませんか?
すいません。 「.Value」にて入力してください。
確認もせず前回、回答してしまいました。申し訳ないです。
※Value以外にも方法がある・・・?無知な為この方法しかしりません。

また、タイプを設定する場合は
>ADOQuery1.Parameters.ParamByName('B_NAME').DataType := ftString;
の様に設定が可能です。

※DB関係でエラーが出た場合は、バグ出しが難しいですよね。
SQLのミスなのか、ParamByName等の記述ミスなのか・・・
とりあえず自分が使っているバグ発見の方法は

  Memo1.Lines.Add(ADOQuery1.SQL.Text);

  try
    //SQL 実行
    ADOQuery1.Open;
//または    ADOQuery1.ExecSQL;

  except on E : Exception do
    begin
      ShowMessage('失敗!' + #10#13 + E.Message);
      Exit;
    end;
  end;
みたいな感じでSQL文の確認とエラー時のメッセージを確認するだけで、解決の糸口が見つかるかもしれません。


もも  2009-07-22 19:59:53  No: 35190

いつもお世話になります。
  ご教授ありがとうございます。
  また、頑張ってみます。

  急激にバタバターー。と進んだと思えば、また壁にぶつかって
悩んでいます。周囲に相談出来る人がおらず、辛抱できずに
このサイトを頼ってしまいます。


HOta  2009-07-22 23:32:06  No: 35191

>ADOQuery1.SQL.Add('UPDATE Name_Table');
>ADOQuery1.SQL.Add('SET ');
>ADOQuery1.SQL.Add('区分名称         = :_区分名称,');
は問題ないでしょう。SQLはTStringsですから、くっつきません。

ADOQuery1.SQL.SaveToFile('ファイル名');
セットしたSQLをファイルに書き出して、直接SQL文を実行してみたら
判りやすくなるかもしれません。


思い込み  2009-07-23 20:25:14  No: 35192

エラーがでないといわれているのでSQLの構文に問題はなくExecSQLは正常に終了していると理解します。
(サンプルでは SETの前, WHEREの前 , ANDの前後にスペースがありませんが、実際はあると理解します。
スペースがなければ構文エラーでExecSQLを通過しないはず)

この程度のパラメータクエリが正常に動かないということは考えられません。
「区分名称」と「名称区分」の無いサンプルDBをACCESSで作成して「ももさん」のコーディングを
コピーして実行してみましたがパラメータクエリできちんと更新されました。

通常、DBエンジンがエラーを出さない場合、DB処理としては100%正常に処理されています。
それなのに思った結果が得られないのは、与えているデータ側に問題がある場合が大半です。
既に確認済みで問題ないと分かっているのならゴメンナサイですが、与えているデータが正常か確認してみましたか?。

WHERE条件に合致する(UPDATE対象)のデータは実際に存在しますか?
WHERE条件のパラメータに与えるデータは間違っていませんか?
対象デーががない時、UPDATE文は正常に終了しますが、当然なにも起こりません。
あるいはパラメータに与えたデータがが間違っている時、上の場合と同様に何も処理されないか、
または、与えたデータ通りに処理されているのに、プログラマー側は思い込みで違うデータを見て処理されていないと判断している(なーんて言うこともちょくちょくあります)

g2_int_wk はどこからくるデータか分かりませんが、思ったとおりの正常なデータが渡されていますか?

ExecSQLの行にブレークポイントを設定して、パラメータとして渡すデータが正常か確認してみたらどうですか。

SQL文そのものには問題なさそうなので、SQL処理以外のどこかに、思い込みとか勘違いが入り込んでいるような気がします。
ところで、DBは何をお使いでしょうか?

老婆心ながら、SET句の
>ADOQuery1.SQL.Add('名称№           = :_名称№,');
は不要なのでは?
害にはなりませんが、WHERE句での検出条件と同じ内容でUPDATEするのは無意味です。


思い込み  2009-07-23 23:06:23  No: 35193

>ところで、DBは何をお使いでしょうか?
以前の ももさんの 質問でどこかにMS ACCESS2003と書いてありましたね。
よく見ていなかったもので、ゴメンナサイ


DEKO  2009-07-24 11:00:38  No: 35194

> (サンプルでは SETの前, WHEREの前 , ANDの前後にスペースがありませんが、実際はあると理解します。
> スペースがなければ構文エラーでExecSQLを通過しないはず)
HOtaさんが仰っているように、SQL.Add() の場合には前後のスペースは不要です。


もも  2009-07-25 01:15:30  No: 35195

いつもお世話になります。
  皆様からご教授頂いたとおり1つ1つ確認して修正しましたところ、
上手くテーブル更新することが出来ました。正直、少し疲れました。(T_T)
  SQL文って結構大変ですね。実感しました。
  コーディングが多くなってもADOQuery1.Parameters.ParamByNameを
使用した方が個人的にはピッタと来ます。
  また、よろしくお願い致します。


HOta  2009-07-26 17:04:43  No: 35196

問題がどこにあって、どのようにすると解決したかを
書いていただけませんでしょうか?
ここは、共有財産ですから。


もも  2009-07-27 19:00:51  No: 35197

いつもお世話になります。
>ADOQuery1.SQL.Add('名称№           = :_名称№,');
  ご指摘を頂いた↑上記の記述を削除しました。
  あとはスペースの挿入などです。

  試行錯誤で修正を重ねているので、他にも修正箇所が
あるかもしれません。このあたりは、技術的に初心者です
ので的確にお答えすることが不可能です。ご勘弁下さい。


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

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






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