- PR -

update。

1
投稿者投稿内容
sachiko
常連さん
会議室デビュー日: 2003/11/26
投稿数: 36
投稿日時: 2003-12-30 18:27
履歴テーブル(主キーなし)にデータセットの値をアップデートしたいのですが、
アップデートしてくれません。
私はvs.netを使用しているのですが、主キーのないテーブルを元にoledbデータアダプターを作成するとupdateコマンドが作成されないので、自分でSQL文を書き作成したのですが、だめでした。
さらに私のデータセットにはコラム同士を掛け算してその答えをコラム3というところに入れてあり、
データ列 '計算' は計算列であるため、ソ-ス列 '計算' からの列マップは失敗しました。というエラー文が表示されてしまいます。
ヒント等いただけたらと思っております。
どうか宜しくお願いいたします。
sachiko
常連さん
会議室デビュー日: 2003/11/26
投稿数: 36
投稿日時: 2003-12-31 02:37
自己スレです。テーブルの始めにオートナンバーの主キーをつけることで実装できました。
しかし以下のコードを動かすと、テーブルにデータグリッド上の初めの2件のデータしか書き込まれません。
この主キーの部分を数値型にしておくと、正しく読み込まれます。この違いは何なのでしょうか・・・。

主キーをオートナンバー型にすると、da_money.Update(ds_money1,"T会費");部分で、'System.Data.OleDb.OleDbException' のハンドルされていない例外が system.data.dll で発生しました。とだけエラーが表示されます。
どうかご教授願えればと思います。宜しくお願いいたします。
private void button1_Click(object sender, System.EventArgs e)
{
string date = DateTime.Today.ToString("d");
TimeSpan t = DateTime.Now.TimeOfDay;
string time= String.Format("{0:d}:{1:d}:{2:d}",t.Hours,t.Minutes,t.Seconds);
System.IO.StreamReader streamReader = new System.IO.StreamReader("c:\\会費\\money.CSV", System.Text.Encoding.GetEncoding(932));
while (streamReader.Peek() != -1)
{
string[] stringBuffer;
stringBuffer = streamReader.ReadLine().Split(',');
//DataSetの作成
DataRow row = ds_money1.Tables["T会費"].NewRow();
for (int counter = 0; counter < stringBuffer.Length; counter++)
{
row["入力日"]=date;
row["入力時刻"]=time;
row[counter] = stringBuffer[counter];
}
ds_money1.Tables["T会費"].Rows.Add(row);
}
streamReader.Close();

dataGrid1.DataSource =ds_money1;
dataGrid1.DataMember = "T会費";

}

private void button2_Click(object sender, System.EventArgs e)
{
da_money.Update(ds_money1,"T会費");
}


[ メッセージ編集済み 編集者: sachi 編集日時 2003-12-31 02:51 ]
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2003-12-31 07:06
NewDataRowと、Rows.Addはforループの中。1個しか作っていませんよ(そして、その1個を上書きしている)。

デバッガで止めながら、値を確認すればそういうことはわかると思います。過去のいくつかの質問も、デバッグのしかた次第ですぐわかることのように思います。デバッグのしかたは、日経ソフトウェアなどの比較的初歩から中級まで扱った雑誌で、毎年のように特集されますから、バックナンバーか縮刷CDを購入されてはいかがでしょうか。
sachiko
常連さん
会議室デビュー日: 2003/11/26
投稿数: 36
投稿日時: 2003-12-31 18:33
コードのだめな点が見えてきません。
NewDataRowと、Rows.Addはforループの中に入れないとだめだということでしょうか?
Jubei
ぬし
会議室デビュー日: 2002/03/02
投稿数: 830
お住まい・勤務地: 関西
投稿日時: 2003-12-31 23:57
こんにちわ。諸農です。

テーブルスキーマの情報がわからないので憶測になるのですが。

引用:

sachiさんの書き込み (2003-12-31 02:37) より:

自己スレです。テーブルの始めにオートナンバーの主キーをつけることで実装できました。
しかし以下のコードを動かすと、テーブルにデータグリッド上の初めの2件のデータしか書き込まれません。
この主キーの部分を数値型にしておくと、正しく読み込まれます。この違いは何なのでしょうか・・・。



オートナンバー型のカラムって、0番目に位置しているって事ないですか?
そうすると、forループの中でcounter値が0から開始されているので、
レコードスキーマのオートナンバーカラムに、CSVデータから取得した
stringBuffer値の最初の値が書き込まれているように思われるのですが、
いかがでしょうか?

-補足-
多分ですが、入力日付や時間などのフィールドも上書きされていますよ。
-再度補足-
というよりも、forループの中で入力日付と時刻のフィールドに、
ループごとに毎回固定値をセットしているコード自体、変です。
それとも、ほんの数ミリ秒内に発生する、最新日付と時刻をセットしているつもり?



#このコード、最近、別の方にコメントした時のコードによく似ていますが、
#他の方のコードを流用する時は、そのコードの意味や使い方などをなどを
#よく理解・検討された上で利用しないと、問題発生時にドツボにはまりますよ。

ではでは(^^)/



_________________
諸農和岳
Powered by Borland Delphi/C++Builder & Microsoft VS.NET

[ メッセージ編集済み 編集者: Jubei 編集日時 2004-01-01 00:03 ]

[ メッセージ編集済み 編集者: Jubei 編集日時 2004-01-01 00:07 ]
sachiko
常連さん
会議室デビュー日: 2003/11/26
投稿数: 36
投稿日時: 2004-01-01 01:46
新年明けましておめでとうございます!
すいません。訂正前のコードを入力してしまいました。こちらが訂正後です。
データベースは主キーを数値型にしてあります。
CSVのデータの1列目に1〜の数字が入力されていて、そのまま登録される形にしてあります。
while (streamReader.Peek() != -1)でその中にFor to文を入れているので、上書きはされていないと思うのですが・・・。
まだまだ始めたばかりなので、手を焼くところがあるとはございますが、よろしければ、色々教えていただけたらと思います。
宜しくお願いいたします。

private void button1_Click(object sender, System.EventArgs e)
{
da_money.Fill(ds_money1);
System.IO.StreamReader streamReader = new System.IO.StreamReader("c:\\会費\\money.CSV", System.Text.Encoding.GetEncoding(932));
while (streamReader.Peek() != -1)
{
string date = DateTime.Today.ToString("d");
TimeSpan t = DateTime.Now.TimeOfDay;
string time= String.Format("{0:d}:{1:d}:{2:d}",t.Hours,t.Minutes,t.Seconds);
string[] stringBuffer;
stringBuffer = streamReader.ReadLine().Split(',');
DataRow row = ds_money1.Tables["T会費"].NewRow();
row["入力日"]=date;
row["入力時刻"]=time;
//DataSetの作成
for (int counter = 0; counter < stringBuffer.Length; counter++)
{
row[counter] = stringBuffer[counter];
}
ds_money1.Tables["T会費"].Rows.Add(row);
}
streamReader.Close();

dataGrid1.DataSource =ds_money1;
dataGrid1.DataMember = "T会費";

}

private void button2_Click(object sender, System.EventArgs e)
{
da_money.Update(ds_money1,"T会費");
}
Jubei
ぬし
会議室デビュー日: 2002/03/02
投稿数: 830
お住まい・勤務地: 関西
投稿日時: 2004-01-01 07:11
こんにちわ。諸農です。

引用:

sachiさんの書き込み (2004-01-01 01:46) より:

データベースは主キーを数値型にしてあります。
CSVのデータの1列目に1〜の数字が入力されていて、そのまま登録される形にしてあります。



「CSVのデータの1列目に〜」の意味が判りません。
何を意図しているんですか?

アップされているコードを引用します。★マークは私のコメントです。
コード:
    //★ここでCSVデータから読み出した1行のデータを「,」で分解しています。
    string[] stringBuffer;
    stringBuffer = streamReader.ReadLine().Split(','); 

    //★金額などが""でくくられている場合を想定すると
    //★あまり上等な手段に思えませんが


    //★新規で1行分のデータ行を作成
    DataRow row = ds_money1.Tables["T会費"].NewRow(); 

    //★フィールドの入力日と入力時刻にデータをセット
    row["入力日"]=date;
    row["入力時刻"]=time;

    //DataSetの作成
    //★↑データセットを作っているんですか?
    //★これの意味がよくわかりません。

    //★↓stringBufferの配列0番目から配列の最後までを。。。
    for (int counter = 0; counter < stringBuffer.Length; counter++) 
    {
        //★↓データ行のカラムフィールドの0番目から順にセットする。。???
        row[counter] = stringBuffer[counter];
        //★なのに、

        //「For to文を入れているので、上書きはされていないと思うのですが・・・。 」
        //★と発言されている意味が、わかりません。

    } 

    ds_money1.Tables["T会費"].Rows.Add(row);
}



なぜ、スキーマ情報を開示してくれないのですか?

仕方が無いのでスキーマを次のように仮定します。
★他の人の発言内容から拝借しています。

0番目:オートナンバー
1番目:会員番号
2番目:年度
3番目:入金予定額
4番目:入金金額
5番目:入金年月日
6番目:入力日
7番目:入力時刻
8番目:更新日
9番目:入力者ID
10番目:更新者ID

対して、CSVの中身が次の通りと仮定します。

0番目:会員番号
1番目:年度
2番目:入金予定額
3番目:入金金額
4番目:入金年月日
5番目:入力者ID
6番目:更新者ID

stringBufferに格納されている情報の0番目から順に処理を行うつもりで、
ループさせているのだとおもいますが、その時のデータテーブルの行に対する操作は

row[counter] = stringBuffer[counter];

のコードをforループで括っていますが、つまり、これを書き換えると、

row[0] = stringBuffer[0];
row[1] = stringBuffer[1];
row[2] = stringBuffer[2];
row[3] = stringBuffer[3];
row[4] = stringBuffer[4];
row[5] = stringBuffer[5];
row[6] = stringBuffer[6];

となります。
row[0]は、スキーマでみるとオートナンバーフィールドですね。
対して、CSVから読み出した値は「会員番号」です。
同様に、データ行の「入力日」は「6番目」ですが、forループの中では
CSVデータの「更新者ID」がセットされていることになりませんか?


いずれにせよ、格納したいテーブルのスキーマ情報をもう一度良く確認するべきです。

そして、他の人のコメントの意味を、よく把握し、自分のコードへのデバッグの材料に
するべきです。

既にコメントもありましたが、デバッグをちゃんと行っていれば、
もっと早い段階でこの現象に気付くはずです。

そして、先のコメントにも書いていますが、開示するべき情報は開示してください。
そうしないのであれば、どんなに言葉を並べたとしても、他の方からの協力を
得ることは無いでしょうね。


ではでは(^^)/
_________________
諸農和岳
Powered by Turbo Delphi & Microsoft Visual Studio 2005

十兵衛@わんくま同盟
http://blogs.wankuma.com/jubei/
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2004-01-02 22:44
 コードを書かれても読む気にはなかなかならないので、何をしているかを箇条書きにするほうが読んでもらえます。他人の書いたコードを読むのは、とてもつらい作業です(そう思いませんか?)。私が読み違えているのか、コーディングが間違えているのか、判別できません。
コード:
private void button1_Click(object sender, System.EventArgs e)
{
	string date = DateTime.Today.ToString("d"); 
	TimeSpan t = DateTime.Now.TimeOfDay;
	string time= String.Format("{0:d}:{1:d}:{2:d}"
		,t.Hours,t.Minutes,t.Seconds); 	
	System.IO.StreamReader streamReader
		= new System.IO.StreamReader(
		"c:\会費\money.CSV", System.Text.Encoding.GetEncoding(932));
	// CSVファイルを読み込むループ
	while (streamReader.Peek() != -1)
	{ 
		string[] stringBuffer;
		stringBuffer = streamReader.ReadLine().Split(','); 
		// 新しい行を作成する 
		DataRow row = ds_money1.Tables["T会費"].NewRow(); 
		// ??このループは何のループ??
		for (int counter = 0; counter < stringBuffer.Length; counter++) 
		{ 
			row["入力日"]=date;
			row["入力時刻"]=time;
			row[counter] = stringBuffer[counter];
		}
		ds_money1.Tables["T会費"].Rows.Add(row);
	}
	streamReader.Close();
	
	dataGrid1.DataSource =ds_money1; 
	dataGrid1.DataMember = "T会費";
	
}



 斜体で引用したループは、何をしたいのでしょう?「row["入力日"]」とあるので、ここが行のデータを読み込んでいるのだと思ったのですが、よく見返せば違うようです。この固定2列への代入が余分なようです。また、諸農さんの指摘のように、コメントのつけ方も間違っています。

 繰り返しますが、他人のコードを読む作業は、とても労力がいる作業です。できれば、していることを箇条書きにしてあらわしてください。そのほうが、読むほうが見やすいだけでなく、まとめている最中に自分で間違いを見つけることもできます。コードの提示は、実際にどのようにコーディングしているのか聞かれてからでかまいません。
#まぁ、どちらも一長一短なんですけどね。。。
1

スキルアップ/キャリアアップ(JOB@IT)