TQuery.ExecSQLについて

解決


小雪  2005-02-01 04:31:49  No: 12977

var
  SqlStr : string;
begin
  (略)

  TForm.TQuery.SQL.Add( SqlStr );
  TForm.TQuery.ExecSQL;
end;

以上の様なプログラムを作成したのですがSqlStrにINSERT文を入れるとエラーが発生してしまいます。
ヘルプには「ExecSQL」はINSERT、UPDATE、DELETEなど実行可能と記載されておりましたが、実際できません。
これは私のSQL作成に問題があるのでしょうか。


HOta  2005-02-01 07:22:20  No: 12978

残念ながら、多分、SQL文がおかしいのでしょう。
このSqlStrの中身を、例えばInterBaseなら、
iSQLで実行してみて、SQL文そのものを調べてみましょう。
一度見せてください。


大豆Z  2005-02-01 09:30:56  No: 12979

Tableしかつかったことないですけど(しかも8年くらい前(^_^;))
とおーぃ記憶を呼び戻して  うっぅうって作ってみました。
とりあえず・・・
Query
2通りあるみたいですね。  作ってみました
参考にならないでしょうけど・・・
Delphi2Desktopで書きましたら、どれでもたぶん動くでしょう。

D2005起動が遅いから使う気になれないけどぉ(>_<)
念のため2005でも確認しました(^_^;)

openする時の   Query1.RequestLive;  の値が要注意ですね。

procedure TForm1.Button2Click(Sender: TObject);
  var Str: string;
      RLive : Boolean;
begin
// Database 1.dbf  a,b,c 文字列型

//  Query1.SQL.text := ' SELECT * FROM "1.dbf"';
// 普通に挿入
  RLive := Query1.RequestLive;
  if Not(RLive) then
   begin
     Query1.close;
     Query1.RequestLive := True;
     Query1.open;
   end;

   // TQuery で INSERT ができない
   // http://www.borland.co.jp/qanda/delphi/d0000242.html
   //  このページあってるの?  逆のことしたらできるんだけど・・・
   // open する前にTrueに設定しないといけないっぽい。

  Query1.Insert;
   Query1.FieldByName('a').AsString  := '1';
   Query1.FieldByName('b').AsString  := '2';
   Query1.FieldByName('c').AsString  := TimeToStr(now);
  { ここで他の項目に値を代入します }
//  if { 項目を更新する場合 } then Post
//  else { 更新を中止する場合 } Cancel;
  Query1.Post;

// まとめて挿入
  Str := Query1.SQL.text;
  // 一度セレクト文破棄
  // SQLの文法知らないので使い方がわからない。
  Query1.SQL.text := 'INSERT into "1.dbf"(a,b,c) VALUES("a","b","c") ';
  Query1.ExecSQL;
  Query1.SQL.text := Str;
  Query1.RequestLive := RLive;
  Query1.open;
end;

> D2  ヘルプより引用
> RequestLive プロパティ
> 説明

> デフォルトの設定では,TQuery は読み出し専用結果セットを返します。ライブ結果セットが必要な場合は RequestLive を True に設定します。問い合わせの SELECT 構文がライブ結果セットの構文条件に従っていれば,BDE はライブ結果セットを返します。RequestLive が True であっても,構文が条件に従っていないと BDE は (ローカル SQL に対しては) 読み出し専用結果セット,(パススルー SQL に対しては) エラーコードを返します。問い合わせがライブ結果セットを返した場合,Delphi は CanModify プロパティを True に設定します。

> RequestLive  CanModify  結果セットの種類

> False  False  読み出し専用結果セット

> True (SELECT 構文が 条件に従う場合)  True  ライブ結果セット

> True (SELECT 構文が 条件に従わない場合)  False  読み出し専用結果セット

↓このB社の説明はなっとくできない。
http://www.borland.co.jp/qanda/delphi/d0000242.html


大豆Z  2005-02-01 10:46:07  No: 12980

http://www.borland.co.jp/qanda/delphi/d0000242.html
↑は、そのうち修正してもらうからいいとして、  

上の引用ヘルプを見ていたら
 CanModify を確認してみると書き込めるかわかりそうなきがしてきしたので修正。

  if Not(Query1.CanModify) then
   begin
     Query1.close;
     Query1.RequestLive := True;
     Query1.open;
   end;

っていうふうにかきかえてみました。♪


@っしー  2005-02-01 20:01:08  No: 12981

EDBEngineError 例外の処理 
http://www.borland.co.jp/tips/delphi/dh012/index.html

で、エラーを表示させるとか。

先ずは、Delphiのバージョン、使用されてるデータベース、SQL文を明記してくださいね。


小雪  2005-02-02 19:34:22  No: 12982

HOta様、@っしー様

質問の答えかどうか分かりませんが、「SqlStr」の中に新規テーブルを作成するSQLを格納しているのです。
それでTTableが存在してなかった為にエラーが起きていた様です(TTableを設置したらエラー回避しましたので)。

因みに

TForm.TQuery.ExecSQL;

の後はTQueryは閉じてしまうのでしょうか。


小雪  2005-02-02 19:52:30  No: 12983

因みに以下の様なエラーメッセージなのですが…

-----------------------------
○○…TQuery名

(○○:データセットは閉じているため、この操作は実行できません。)
処理を終了します。
-----------------------------


通りすがり  2005-02-02 20:33:21  No: 12984

状況がよくわかりませんが、、、
var
  TblName: string;
  SqlStr: string;
begin
  TblName := 'C:\TEST.DB';
  //
  SqlStr := 'CREATE TABLE '''+TblName+''''+
            ' (LAST_NAME CHAR(20),'+
            ' FIRST_NAME CHAR(15),'+
            ' DEPT_NO SMALLINT,'+
            ' PRIMARY KEY(LAST_NAME, FIRST_NAME))';
  Query1.SQL.Clear;
  Query1.SQL.Add(SqlStr);
  Query1.ExecSQL;
  //
  SqlStr := 'INSERT INTO '''+TblName+''''+
            ' (LAST_NAME,FIRST_NAME,DEPT_NO)'+
            ' VALUES (''通り'',''すがり'',1)';
  Query1.SQL.Clear;
  Query1.SQL.Add(SqlStr);
  Query1.ExecSQL;
end;
ってすると、新規にテーブルを作成し、そのテーブルにレコードを挿入できます。
Paradox/D6です。


AY  2005-02-02 21:59:26  No: 12985

ExecSQLは、結果(レコード)を返さない実行なので、openは不要です。
SELECT文の場合は、Open/Closeが必要です。
ExecSQlは直接SQL文を実行するのですから、TTableがあるかどうかは
本来関係ありません。
そもそも、Insert文だったのが、テーブル作成SQl・・になっていて
状況が  わかり辛いです。
やはり、SQL文を書かれたほうが  皆さん解りやすいと思いますが・・


大豆Z  2005-02-03 01:56:47  No: 12986

> は、そのうち修正してもらうからいいとして、  
Delphi の Q&A  
もう修正されているよ
びっくり(・〇・;)したぁー


久慈  2005-02-04 01:06:25  No: 12987

「データセットは閉じているため、この操作は実行できません」
私もこのエラーが出たことがあります。
通りすがりさんがおっしゃるように、ExecSQLは結果を返さない処理です。
この処理をしても自動的にQuery1.openにはなりません。
プログラムのどこかに、Query1.openを前提としたコードが書かれている可能性があるような気がします。
まずテーブルにデータが書き込まれているかどうかを調べてみたら如何でしょうか?


小雪  2005-02-04 04:17:33  No: 12988

通りすがり様、AY様、久慈様

「TQuery.Open」を実行したらエラー回避できました
ありがとうございました〜


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

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






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