質問者
再び「同時実行違反」について

質問
すべての返信
-
前のスレの続きになりますが、空白とかそういう問題じゃないない気がします。データ更新部分をどのように作成されているのかわからないのですが、もう一度DataAdapterの部分を作り直してみられたらいかがでしょうか?
ちなみにmdbをSqlDataAdapterを通してDataTableをDataGridViewにバインドするテストコードを書いてみましたが、特に同時実行違反が起こることはありません。
同時実行違反が起こる心配がないのであれば、DataAdapterの構成ウィザードで、オプティミスティック同時実行制御にチェックをつけなければいいだけですが、できればこうせずに解決したいところですよね。単なる意地ですが。(^^;#もしくは.NET2.0的にTableAdapterを使ってみてもいいかもしれません。
-
MDB だから OleDbDataAdapter では?
それはさておき、オプティミスティックス同時実行制御の SQL は許容できますか?
私は論外だと思っています。
データの件数が少なければ、別にどうってことないですが、件数が多ければ Update するときにとんでもなくコストを払うことになります。
MDB には GUID や TIMESTAMP が無いので、ロジック的にコントロールすることになると思いますが、できれば SQL Server 2005 Express (将来的には MDB に変わる機構が提供される予定)を使ったほうが良いように思いますが。 -
おがわみつぎ さんからの引用 MDB だから OleDbDataAdapter では?
すみません。OleDbDataAdapterの書き間違えでした。m(_ _)m
その他の同時実行制御などについては、私も全面的にそう思います。
それに本当に同時実行制御が必要ならば、複数のユーザーが同時に使うことが想定されるわけで、そうなれば規模にもよりますが、MDBでは力不足でしょう。であれば、今からSQL Server 2005 Expressを使っておけば、簡単にSQL Server 2005を使った本格的なクラサバシステムへ移行することもできるので、こちらを使われる方がお勧めだと思います。#でも、MDBで今回の障害の原因を突き止めることも、大事な勉強だと思いますので、今すぐにMDBをやめた方がいいという意味ではありません。時間が許せばですが。
-
trapemiya さんからの引用 SQL Server 2005 Expressを使っておけば、簡単にSQL Server 2005を使った本格的なクラサバシステムへ移行することもできるので、こちらを使われる方がお勧めだと思います。
Management Studioを使ってSQL Server 2005 Expressのデータベースを作りました。
SQL Server 2005 Expressを使うのは初めてです。C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\Dataに作ったデータベースがあるようです。ファイルの種類は「SQL Server Database Primary Data File」となっております。
これをコピーしてVSのプロジェクトファイルを格納してあるフォルダに移動させると,「ファイルのコピーエラー」になってしまいます。コピーするためには,何か別の操作が必要なのでしょうか?。お教え願います。
-
「ひと目でわかるMicrosoft SQL Server 2005」
「SQL Server 2005ではじめよう データベースシステム開発入門」
辺りが出版されているようです。
#「SQL Server2000でいってみよう」は、SQL Server 2000を対象にした内容ですが、SQL Serverというデータベースに関して、大変わかりやすく簡潔にまとまっていますので、SQL Server 2005を学ぶ上でも大いに役立つと思います。お勧めです。
zen73 さんからの引用
これをコピーしてVSのプロジェクトファイルを格納してあるフォルダに移動させると,「ファイルのコピーエラー」になってしまいます。コピーするためには,何か別の操作が必要なのでしょうか?。お教え願います。
コピーや移動をする必要はありません。そのまま、アプリケーションやVS2005から接続しにいきます。
他のコンピュータへ持っていく時には、他のコンピュータにもSQL Server 2005 Expressがインストールされている必要があり、それに持っていったデータベースファイル(.mdf ファイル)がアタッチされる形になります。この辺りはまだMDBのような手軽さはありません。 -
稚拙ですが、私のブログを参考にしてみてください。
[SQLEXPRESS]SQL Server 2005 Express の AttachDBFilename/User Instance を利用した開発について -
SQL Server 2005 Express は,サービスとして動いているので,
Accessユーザーにしてみると,微妙に使いづらいかもしれませんね。JETデータベースエンジンは,いわゆる DLL なので,
アプリケーション・プロセスにロードされて使われるので,
使っていない時は,MDBファイルも使っていない時になるわけです。一方,SQL Server 2005 Express は,
デフォルトの状態でそのままインストールすると,
SQL Server のサービスが自動起動するように構成されるので,
データベースがSQL Server のインスタンスに登録されていれば,
すでに起動しているので使用中になっているということですね。管理ツール -> サービス -> SQL Server (SQLEXPRESS) のところを
右クリック -> プロパティ
で,スタートアップの種類 が 自動 になっているのを確認できると思います。
サービスとして動いているSQL Serverを止めれば,
使用中ではなくなるのでコピーはできるようになります。でも,.mdfデータファイルごとコピーするのなら,
ふつうは,上で出てきているように デタッチしてからです。デタッチは,
SQL Server Management Studio Express でも,GUIで楽できた筈です。
(データベース名を右クリック -> タスク -> デタッチ... )一度,データファイルをデタッチしておけば,
上のテクニックでJETっぽく使えますね。# JETっぽくでなく,さらにJETらしい使い方というか,
# サービスでなくDLL版?のもの(SQL Server Everywhere)がもうじき?出るそうですし,
# ローカルのデータをSQL Serverで利用するのも,選択肢が増えて,
# 小回りがきくようになるでしょう。
# スタンドアロンでは,それの方を気に入る人が多いような気がします。 -
UpdateCommandをTableAdapterのプロパティで設定しようとしていますがうまくいきません。近所の本屋に紹介いただいた本が全てありましたので目を通してみましたがこれに関する記述はどれにもありませんでした。ネットでも検索できないし,お手上げ状態です。
更新したいのは,T_学力テーブルの国語~平均です。なおT_学力テーブルにはキーは設定していません。
甘えてばかりですが,UpdateCommandのかきかたを教えていただけないでしょうか?
SELECT T_学力.ID, T_学力.学年, T_学力.回数, T_名簿.年, T_名簿.組,
T_名簿.NO, T_名簿.氏名, T_学力.国語, T_学力.数学, T_学力.社会,
T_学力.理科, T_学力.英語, T_学力.合計, T_学力.平均
FROM T_学力 INNER JOIN T_名簿 ON T_学力.ID = T_名簿.ID
ORDER BY T_名簿.NO -
zen73 さんからの引用
[ID] [学年] [回数] [国語]・・・・[英語] [合計] [平均]
1101 1 1 80 70 400 80
1101 1 2 70 90 390 78
1101 1 3 75 85 410 82
1101 2 1 90 75 420 84
というように,IDを個人の識別番号としてテストデータを蓄積していこうと思っているのですが,キーを設定するとIDの重複は許されないのではないでしょうか。それともこのようなきーを設定しないテーブルは設計ミスということになるのでしょうか。
このようなケースでは必要ないです。しかし、レコードを一意に識別するために、このテーブルのID値を付ける場合も無くはありません。[ID1] [ID] [学年] [回数] [国語]・・・・[英語] [合計] [平均]
1 1101 1 1 80 70 400 80
2 1101 1 2 70 90 390 78
3 1101 1 3 75 85 410 82
4 1101 2 1 90 75 420 84zen73 さんからの引用
UpdateCommandをTableAdapterのプロパティで設定しようとしていますがうまくいきません。
TableAdapterのUpdateCommandやSelectCommandなど全てのCommand系オブジェクトは、直接いじれないようになっています。TableAdapterという枠組みの中で、ウィザードによって内部的に生成されたこれらのDataAdapterのCommand系オブジェクトを、勝手にいじられては困るということなのかもしれません。それはさておき、単にUpdate文を使うだけでしたら、SqlCommandでUpdate文を発行すれば良いと思いますが、TableAdapterで行いたい場合には、次の手順になります。
1.データからデータソースの表示をクリック。
2.データソースの画面で右クリックして、新しいデータソースの追加。
3.データベースを選らんで次へ。新しい接続で接続を作成して次へ。
4.データセット内に指定するデータベースオブジェクトはとりあえずどこにもチェックを付けずに完了。ワーニングが出ますが、そのままはいを選んで続行。
これでデータソース画面に型付けされたデータセットができました。
5.データソース画面でそのデータセットを選択し、右クリックして、デザイナでDataSetを編集をクリック。
6.グレーの横じまだらけの画面が出ます。そこで右クリックして、追加でQueryを選択。
7.データ接続を選んで次へ。とりあえずSQLステートメントを使用するを選択して次へ。(ここで私は通常、新しいストアドプロシージャの作成を選びますが)
8.UPDATEを選択して次へ。
9.クエリビルダを起動します。右クリックしてテーブルを追加。
10.UPDATE TABLE1 SET TEST1=@TEST1, TEST2=@TEST2 WHERE TESTID=@TESTID
のような感じでSQL文を作成して次へ。
11.関数名を指定して次へでUpdate文が生成される。
12.ここで一度アプリケーションをビルド。
13.上のビルドによって、ツールボックスに上で作成されてTableAdapterが追加されていますので、それをフォームにドラッグ。(デフォでQueriesTableAapter)
14.あとはコードでqueriesTableAapter1.上で付けた関数名(パラメータ1, パラメータ2, ・・・)ただ、2つ以上のテーブルを同時にセットで更新となると、上のパターンではダメです。トランザクションを切って、SqlCommandで2つのテーブルを更新するか、2つのテーブルをトランザクションを切って一度に更新するストアドプロシージャを作成して、それをTableAdapterで使うというような感じになると思います。
# 手術大変ですね。がんばって下さい。
-
trapemiya さんからの引用
このようなケースでは必要ないです。しかし、レコードを一意に識別するために、このテーブルのID値を付ける場合も無くはありません。
中さんから突っ込まれそうなんで、フォローしときます。(^^; 必要ないとは絶対にキーを設けるなという意味ではありません。#さっき編集してたらまた???になって、その投稿を削除した時に子が居ますって言われて、えっ?と思ったんですが、中さんの投稿をひょっとして消しちゃいました。もし、そうならごめんなさい。m(_ _)m
#長い文章を編集して???に変わるのは痛い。早く、直してほしいなぁ。
-
trapemiya さんからの引用
ただ、2つ以上のテーブルを同時にセットで更新となると、上のパターンではダメです。トランザクションを切って、SqlCommandで2つのテーブルを更新するか、2つのテーブルをトランザクションを切って一度に更新するストアドプロシージャを作成して、それをTableAdapterで使うというような感じになると思います。
ざくっと調べてみたんですが、Transactionscopeの中で2つのテーブル更新をしてしまえばいいかな?
もしくは、TableAdapterがpartialだから、そこにメソッド作って、その中でSqlTransactionを使って2つのテーブルを更新するという手もありそうですね。 -
私の説明不足のところがありましたので
2つのテーブル「T_名簿」「T_学力」を内部結合してdataGridViewに表示し,
教科の点数を入力した後に,「T_学力」テーブルだけをdataGridViewのデータで更新したいのです。
*それにしても,これからの道のりは私にとってあまりにもハードルが高くて,挑戦する気持ちを萎えさせてしまいがちです。愚痴になりますが,.mdbでは簡単に設定できたUpdateCommandがSQLServerではなぜにこうも複雑なのでしょうか。こんなにも難しいことが<SQLの最初から教えている書籍であれば確実に書いてあります>とは・・・・。すぐにでも同時実行違反を解消できるなどと思っていたのは浅はかでした。 -
mdbでもSQL Serverでも、DataAdapterを使えば、一緒と言っても同じぐらい同じ手順ですし、TableAdapterを使ってもそうです。要は、DataAdapter, DataTable, SqlCommandの組で使うのか、それらを一まとめにして管理するTableAdapterを使うのかの違いです。mdbとSQL Serverの違いではありません。繰り返しになりますが、どちらを使っても同じようなコードになります。同時実行制御に関しても同じです。ただ、SQL Serverだとストアドプロシージャやトリガ、そういった素晴らしい機能を使うことができます。コーディングがほとんど同じなら、SQL Serverを使った方がいいとは思いませんか?
T_学力を更新するのでしたら、OleCommandの代わりにSqlCommandを使うだけです。
TableAdapterのウイザードを使えば、DataAdapterやSqlCommand、DataSet、DataTableなどの知識なしに、データベースが操作できるようになります。実は内部ではこれらが使われています。悪い言い方をすれば、これらADO.NETの知識なしに、簡単に初心者がデータベースを扱えるようにしたものとも言えます。
DataAdapterの構成ウィザードを使ったとしても、そこから先はDataSetやDataTableの知識が要りましたよね。TableAdapterは、それをもっと進めたものだと思えばいいでしょう。
なので、mdbだろがSQL Serverだろうが、接続先が違うだけで、TableAdapterの使い方に違いはありません。 -
trapemiya さんからの引用 それはさておき、単にUpdate文を使うだけでしたら、SqlCommandでUpdate文を発行すれば良いと思いますが、TableAdapterで行いたい場合には、次の手順になります。 14.あとはコードでqueriesTableAapter1.上で付けた関数名(パラメータ1, パラメータ2, ・・・)
いま,UpdateCommand追加のテストをしている所です。
private void button1_Click(object sender, EventArgs e)
{
try
{
int iRows = queriesTableAdapter1.UpdateQuery( ア );
MessageBox.Show("Update " + iRows.ToString());
}
catch (Exception eUP)
{
MessageBox.Show(eUP.Message);
}
}
アのところには,(string ID,string 国語, string 数学)とかくように促されていますが,何を書いたらいいのかわからないでいます。このことについてのアドバイスをお願いします。
---------テスト用のテーブル----------------
SELECT ID, 国語, 数学
FROM T_学力---------追加したUodateCommand---------
UPDATE T_学力
SET ID = @ID, 国語 = @国語, 数学 = @数学
WHERE (ID = @ID) AND (国語 = @国語) AND (数学 = @数学) -
zen73 さんからの引用
.mdbに戻ってUpdateCommandについて検証してみました。
列の一部だけを更新させていたのを,全ての列を更新するようにしてみた所「同時実行違反」が起こらないようになりました。
う~ん、直接関係ないような気がしますが、動いたんですね。あと、mdbの場合は、OleDBTypeから.NET Framework型との間に以下のような変換規則があるので、気をつけて下さい。mdbの日付時刻型はデフォルトでOleDb.OleDbType.DBDateに割り当てられますが、これだと日付部分しか持てないため、同時実行違反がおこる場合があります。この場合、OleDb.OleDbType.Date に変更すれば、時刻部分も含めて比較されますので、同時実行違反がおこりません。その他、以下の2つの表を見比べてみて下さい。DataAdapter によるパラメータの使用
http://msdn2.microsoft.com/ja-JP/library/bbw6zyha.aspxOleDbType 列挙体
http://msdn2.microsoft.com/ja-JP/library/system.data.oledb.oledbtype.aspx