何時もお世話になります。
画面に、TQuery,UpdateSQL,Edit1,Edit2、Buttonを配置、Buttonを押すとアップデートを実行するように、以下のコードを記述しました。2点ほど、わからず、困っています。どなたかご教示ください。
Del6Pro,XpPro,BDEです。
UpDateSQL文は、以下の通りです。
update "User3.db"
set
Memo03 = :Memo03
where
Memo03 = :OLD_Memo03
**ここでひとつ疑問点、
’User3.db:項目名を決定できませんでした。’警告文:
以下記述したコード
procedure TFormSub.Button1Click(Sender: TObject);
var S1,S2,S3 : String;
begin
try
DMSyaken.SyakenMainQuery.DisableControls;
DMSyaken.SyakenMainQuery.Close;
S1 := Edit1.Text;
S2 := Edit2.Text;
DMSyaken.SyakenMainQuery.Open;
DMSyaken.SyakenMainQuery.First;
while not DMSyaken.SyakenMainQuery.Eof do
begin
DMSyaken.SyakenMainQuery.Edit;
if DMSyaken.SyakenMainQuery.FieldByName('Memo03').Text <> '' then
begin
S3 := DMSyaken.SyakenMainQuery.FieldbyName('Memo03').AsString;
S4 := StringReplace(S3,S1,S2,[rfReplaceAll]);
DMSyaken.SyakenMainQuery.FieldByName('Memo03').Text := S4;
DMSyaken.SyakenMainQuery.Post;
DMSyaken.SyakenMainQuery.Next;
end
else
DMSyaken.SyakenMainQuery.Next;
end;
DMSyaken.SyakenMainQuery.ApplyUpdates;
finally
DMSyaken.SyakenMainQuery.EnableControls;
end;
プログラムが暴走してしまう。
TQueryのSQL・UpdateSQLの設定はどうなっていますか?
また、対象のDBは何でしょう?
[項目名を決定できませんでした。]
多分、複数のテーブルを扱っているのでしょうが、同じ項目名が
別のテーブルにあり、決定できないのでしょう。
HOTAさん、いつもレス有難うございます
//TQueryのSQL・UpdateSQLの設定はどうなっていますか?
//また、対象のDBは何でしょう?
TQueryのSQLは以下の通りです
select distinct * from user1.db,user2.db,user3.db
Where (User1.UserID = User2ID)
and (User1.UserID = User3ID)
and (User1.CarID = User3.CarID)
この中の、User3.dbにあるMemo03の項目を変換したいと思っています。
User3.DBのMemo03項目にあるDBEdit1.Text の文字列をEdit2.Textに変換する試みを行っています。
//[項目名を決定できませんでした。]
//多分、複数のテーブルを扱っているのでしょうが、同じ項目名が
//別のテーブルにあり、決定できないのでしょう。
この場合の対処法はどのようにすれば良いのでしょうか?項目名を変更したくないときはどのようにすれば良いのでしょうか?
>select distinct * from user1.db,user2.db,user3.db
>Where (User1.UserID = User2ID)
>and (User1.UserID = User3ID)
>and (User1.CarID = User3.CarID)
この場合、SQL文の中でdistinctが使われていて、
どの行を対象に更新すればよいかわからなくなり、
[項目名を決定できませんでした。]の表示が出ます。
素直に、別にUpdateするためのTQueryを用意して、
そちらで変更しましょう。
TQuery のSQL文を
from ":syakenDB:User3.db" d, ":syakenDB:Car1.db" d1, ":syakenDB:Car2.db" d2, ":syakenDB:Car0.db" d3から
from User3.db as d,User0.db as d1へ変更すると
[項目名を決定できませんでした。]の表示はなくなり、プログラムは正常に動くようです。なんとかこれで解決しました。
//また、対象のDBは何でしょう?
paradox7です。DBに更新をかけるには、単にApplyUpdatesを使うだけでは、ダメなのでしょうか?
何かDBが最初と違っていますね?
UpdateSQLはどのようになっていますか?
更新するレコードが特定できないと、
[項目名を決定できませんでした。]の表示が出ます。
ApplyUpdatesは、TUpdateSQLがCacheに
それまでにUpdateやInsert・deleteしたレコードを貯めておき、
それを元のDBに適用するComandです。
//何かDBが最初と違っていますね?
HOtaさん、アドバイス色々ありがとうございます。色々試行錯誤している中での質問ですので、はずしていることもあるかもしれません。何せ、初心者の初心者なので。
//UpdateSQLはどのようになっていますか?
UpdateSQL1のSQL文は、以下の通りです。
update "User3.db"
set
Memo03 = :Memo03
where
UserId = :OLD_UserId
//更新するレコードが特定できないと、
//[項目名を決定できませんでした。]の表示が出ます。
この問題は、解決できました。
色々、やって最終的には以下のコードに変更しましたが、今度は新しいエラーメッセージ
"テーブルの数が多すぎます.User.table3.db"が出てしまいます。何か、あり地獄に踏み込んだようで、めげそうです。解決策をご教示願います。
procedure TFormSub.Button1Click(Sender: TObject);
var S1,S2,S3,S4,S5 : String; //user0,user3のテーブルのmemo03項目を同時に変換するため
begin
try
//画面のちらつきをなくす目的。
DMSyaken.SyakenMainQuery1.DisableControls;
DMSyaken.SyakenMainQuery1.Close;
S1 := Edit1.Text;
S2 := Edit2.Text;
DMSyaken.SyakenMainQuery1.Open;
DMSyaken.SyakenMainQuery1.First;
while not DMSyaken.SyakenMainQuery1.Eof do
begin
DMSyaken.SyakenMainQuery1.Edit;
if DMSyaken.SyakenMainQuery1.FieldByName('Memo03').Text <> '' then
with DMSyaken.SyakenMainQuery1 do
begin
S3 := DMSyaken.SyakenMainQuery1.Fields[14].Text;
S5 := DMSyaken.SyakenMainQuery1.Fields[50].Text;
S4 := StringReplace(S3,S1,S2,[rfReplaceAll]);
S3 := S4;
S5 := S4;
DMSyaken.SyakenMainQuery1.Post;
DMSyaken.SyakenMainQuery1.Next;
end
else
DMSyaken.SyakenMainQuery1.Next;
end;
finally
DMSyaken.SyakenMainQuery1.EnableControls;
ShowMessage('変換が終わりました');
DMSyaken.DBSyaken.ApplyUpdates([DMSyaken.SyakenMainQuery1]);
end;
end;
ちょっと問題を整理しましょう
まず、SyakenMainQuery1のSQL文は、
>select distinct * from user1.db,user2.db,user3.db
>Where (User1.UserID = User2ID)
>and (User1.UserID = User3ID)
>and (User1.CarID = User3.CarID)
ですね?
そのUpdateSQLのUpdateプロパティは
>update "User3.db"
>set
> Memo03 = :Memo03
>where
> Memo03 = :OLD_Memo03
ですから、"User3.db"のMemo03フィールドを更新するのですね。
でも、このソースからは、編集するフィールドが見あたりません。
これでは変更できていないはずです。
ソースを表示する前に、各テーブルがどうなっているかを
見せてもらえませんか?
HOTAさん、有難うございます。
解りました。今、会社にいるので、自宅に帰ってからメールします。
HOTAさん、親切にありがとうございます。
色々試す内に、大分変わってきて、以下のようになっています。
TQUERY のSQLは
SELECT d.*, d1.*
FROM User3.db as d, User0.db as d1
WHERE
(d1.UserId = d.UserId)
そのUpdateSQLのUpdateプロパティは以下の通りです。
update "User3.db" d
set
d. Memo03 = :Memo03
where
d.UserId = :OLD_UserId
user0.dbは、
userID Name1, Name2, Add1, Add2, Kata, Nen,・・,Memo03,・・・・・と項目が50個あります。
user3.dbは、
userID Name1, Name2, Add1, Add2, Kata, Nen,・・,Memo03,・・・・と項目が16個あります。
上に示した項目名は、同じ項目名が数箇所あります。
やりたいことは、リストボックスに値を表示して、この値をMemo03項目の変更前の値とし、変更後の値をEdit2に書き入れ、ボタンをクリックするとUser0.db,User3.db双方のMemo03項目が変更されるようなプログラムを考えています。
よろしくご教示願います。
すみません。追加です。
User0.db,User3.dbいずれのデータも2000件位のデータで検証しています。
たまに、"テーブルが多すぎます。User3.DB"のエラーメッセージが出ます。
これは、データ数が多すぎるためでしょうか?もしそうであれば、どのような対処法があるのでしょうか?併せて、ご教示ください。
同じ項目名が多いというこっとは、データーバースの設計ができていないことになります。どちらの項目が正しいか判らなくなります。もう一度設計し直しましょう。
データがたかだか2000件でおかしくなることはありません。これは、EDit〜Postがきちんとしていない影響が考えられます。
編集するコードが見あたりません。これでは変更できていないはずです。
一番簡単なのは、選択するTQueryと更新するTQueryを別にする方法もあります。
このまま使うなら、
> begin
> DMSyaken.SyakenMainQuery1.Edit;
> if DMSyaken.SyakenMainQuery1.FieldByName('Memo03').Text <> '' then
> with DMSyaken.SyakenMainQuery1 do
> begin
> S3 := DMSyaken.SyakenMainQuery1.Fields[14].Text;
> S5 := DMSyaken.SyakenMainQuery1.Fields[50].Text;
> S4 := StringReplace(S3,S1,S2,[rfReplaceAll]);
> S3 := S4;
> S5 := S4;
> DMSyaken.SyakenMainQuery1.Post;
> DMSyaken.SyakenMainQuery1.Next;
> end
> else
> DMSyaken.SyakenMainQuery1.Next;
> end;
でEditした後は、必ずPostかCancelをしましょう。そのままNextしてはいけません。また、編集したS4をS3,S5に返していますが、レコードには一切適用していません。これではレコードは変更していません。項目を番号で扱っていますが、名前で扱った方がソースの解読性がよくなります。
with DMSyaken.SyakenMainQuery1 do
while not Eof do
begin
if FieldByName('Memo03').asString <> '' then
begin
Edit; //ここで編集状態にする。
S3 := Fields[14].asString;
S3 := Fields[50].asString;
S4 := StringReplace(S3,S1,S2,[rfReplaceAll]);
Fields[14].asString := S4; //編集した文字列を項目に設定する
Fields[50].asString := S4;
Post; //ポストする
end;
Next;
end;
//この後ApplyUpdatesする
HOTAさん早々のレス有難うございます。
今晩、早速試してみます。
色々ご丁寧なご教示、痛み入ります。
DELPHIを独学中の身、というか本格的なプログラミングは初めての経験で戸惑うというか意味不明のことばかりですが、今後もよろしくお願いします。
DelphiはRAD Toolの中でデーターベースが一番簡単に使えます。
それも、TDataSetから派生したTTablやTQueryがあり、派生元であるTDataSetの使い方は、TTablやTQueryは同じように使えます。また、それぞれの使い方もできます。
TQueryで直接AppendやEditができますが、これ以外に、別のTQueryでInsert・Updateすることもできます。ものによれば、この方が処理が早いことがあります。ただ、プログラムはちょっと複雑になります。
HOtaさん、色々ありがとうございました。
最終的に、User0.dbとUser3.dbにそれぞれTQueryとUpDateSQLを準備し、それぞれのテーブルを別々に変換することによって期待どうりの結果を得ることが出来ました。長い間、懇切丁寧なアドバイス、誠にありがとうございました。
[同じ項目名が多いというこっとは、データーバースの設計ができていないことになります。どちらの項目が正しいか判らなくなります。もう一度設計し直しましょう。]
過去に業務用のソフトを購入しています。このソフトは、そのまま使おうかと考えています。今回は、このソフトのデータを下に、私なりに蓄積したデータを加工や、使いやすいように、あるいは新しい機能を付加したいと思い立って、自分でプログラムを考えていました。従って、テーブルの再設計が出来ないという制約がありました。あしからず、ご了承ください。
すみません
解決のチェックマークを忘れてました
ツイート | ![]() |