ADO.NETの質問・雑談スレ2
ADO.NETに関する質問・雑談・評価 etc 何でもどうぞ。 前スレ ADO.NETの質問・雑談スレ http://pc11.2ch.net/test/read.cgi/db/1104630889/ MSDNだけで十分といえるには、それなりの前提知識がある場合の話でしょ。 例えば、VB5の開発経験がある人だとVB6の習得にかかる時間は・・・みたいな。 それだけの知識が無い場合は、技術評論社などの一般向け書籍を読み、 ADO.NETの公式文書を読み、MSDNという順序しかないと思う。 >>200 プログラマー板のVB.NETスレなどに行って相談してみると いいかもしれない。 ここがスレ違いというわけではないが、情報量が違うから >>202 そうですか。 とりあえずVB.NETの質問スレに行ってみます。 >>200 レポートデザイナ?でいろいろやるより 出来上がりの形までのストアドを作ったほうが楽かもね まぁ確かにそんな気がする。 ただ、前年比みたいなのを混ぜると通貨型と浮動小数点型が混在しちゃうんでどうにかならんかなとか思ったり。 まぁどっちも文字列型に変換してしまうのが手っ取り早いかな。 すみません、質問いいですか? ADO.NETはおろかDB初心者です。 現在SQLServer(2005EE)のデータをC#(VS2008PE)にて操作しようと考えています。 SQLServerからアダプター経由でDatasetに読み込み DataRows.add(hoge) adapter.update で追加更新までは出来るようになりました。 ですが、レコードの削除やセル単位の変更のデータベースへの更新が全く判りません。。。 エスパー様、どうか宜しくお願いいたします。 >>207 DataRow自体の中身を変更したり削除して Updateを呼べば普通は何も考えなくても裏でやってくれる >>208 それが出来ないんですよ・・・・・ Datasetやアダプターになにか設定が必要なのでしょうか? 追加更新はUPDATEであっけなく出来たのですが・・・ わたし勘違いしてますかね? Datasetの中のDataRowを削除、変更してUPDATEしようとしているのですが・・・ >>209 対象のDataRowのstateが変わってないとか? そうであれば、処理の仕方が間違っているんでしょう。 adapter.update前の中身を確認して見ては? >>210 極意の本に載ってた方法でそれもやりましたが だめでした・・・・。 なにか根本的におかしい事をやっている気がします。 どこか参考になるサイトをご存じないでしょうか? >>212 ありがとうございます。 今日の夜でもいいですか? よろしくお願いいたします。 private void button1_Click(object sender , EventArgs e) { DataRow ddd =this.hOGEDataSet1.Tables[0].NewRow(); ddd["NCHAR10"]= "ssssss"; ddd["INT"] = 55; this.hOGEDataSet1.Tables[0].Rows.Add(ddd); this.tESTTableAdapter.Update(this.hOGEDataSet1.TEST); } private void button2_Click(object sender , EventArgs e) { DataRow ddd = this.hOGEDataSet1.Tables[0].Rows[this.hOGEDataSet1.Tables[0].Rows.Count - 1]; this.hOGEDataSet1.Tables[0].Rows.Remove(ddd); this.tESTTableAdapter.Update(this.hOGEDataSet1.TEST); } private void button3_Click(object sender , EventArgs e) { this.hOGEDataSet1.Tables[0].Rows[6]["NCHAR10"] = "huga"; this.tESTTableAdapter.Update(this.hOGEDataSet1.TEST); } ボタン1⇒成功 ボタン2,3⇒失敗 となります。 宜しくお願いします 更新には、変更された行を含む DataRow コレクションが渡されたとき、有効な UpdateCommand が必要です。 例外内容です。 >>215 TableAdapterのUpdateCommandが設定されていないか そこに設定されているSQLがおかしいって事でしょ DeleteCommandの方も同様 >>216 おはようございます。 >TableAdapterのUpdateCommandが設定 すみませんが、デザイナ上で行う方法を教えては頂けないでしょうか? 私なりに例外メッセージ等で調べたのですが、全然判りません・・・ よろしくお願い致します。 >>217 じゃ、プロジェクトファイルをうpってみたらどうかな? デザイナ上ではすべてが出来るわけでもないしさ 「ADO.NETはおろかDB初心者です」っていうのならば、 こういうことをやる前に、SQL文について勉強して おいた方がいいと思う。 SQLがある程度書けるくらいになっておかないと、 概念の理解まで至らないし、これから先もあらゆる ことでつまづきまくると思う。 新しいクラスが出てくると、便利な反面、そのルールや使い方を覚えて 習得しなければならないのが欠点だな。 ADO.NETの場合、欠点のみが表に出ている感がするのだが・・・ 質問です SqlServer2005+DataSet&TableAdapterで、主キーが設定された行の交換をしたいのですが dataSet1.EnforceConstraints = false; DataRow row1 = dataSet1.Table1.Rows[0]; DataRow row2 = dataSet1.Table1.Rows[1]; row1["seq"]=1; row2["seq"]=0; dataSet1.EnforceConstraints = true; Table1TableAdapter.Update(dataSet1.Table1); ←ここで一意違反 Table1にはID+seqの複合主キーが設定してあります デバッガでRowsの中身を確認してみましたが、キーの重複はありませんでした それなのに何故一意違反が出るのか不思議です Table1.Copy()で一旦退避して書き換え、Rows.Clear()→Rows.Add()してもやはりエラーが出てしまいます 一体何が原因なのでしょうか? TableAdapterが使ってるSQLを確認してみれば? 基本的には1行ずつupdateのSQL投げるはずだから、 Rows[0]のupdate文実行しようとしてRows[1]の元データとダブってるんじゃね そもそも主キーカラムに更新なんてかけるもんじゃない。 del/insにするか主キー「以外」のカラムを入れ替えるか。 テーブル内のデータをDELETEで削除したあと、新しいデータをINSTALLで入れるプログラムを 書いたんだけど1万近いデータをforで回しながら入れていくとめちゃ時間かかります なにか高速化する方法はないでしょうか? 俺も「主キーを更新する」という設計の方に問題があるように思うな。 そのフィールドを入替えする必要性があるのであれば、それとは 別に主キーフィールドを準備するべきだ。 >>225 いちいちINSTALLしてるから時間がかかるんじゃないの? >>225 あなたの言う「めちゃ」の基準がどんなものなのかというものがあるし、 極端な話、コネクションのopen/closeをforの中に入れてしまっている 可能性などもあるので、具体的にどういうプログラムを書いているのか、 現状は何秒かかっているのか、何秒くらいにしたいのか、などを 書かないと話はすすまないんじゃないかな。 1万件insertするとどうしてもそこそこ時間がかかる。 1000件ごとにコミット、とかで大幅に速くなる可能性はある。 あとはselect/insert1発で出来るような話ならそうするとか データ入れるときの列の指定に列名を文字列で指定してるとか? わんくまの人でそのパフォーマンス調べてた人いたな。 1行ずつコミットと複数行コミットともひとつあったな。 Decimal型からデータを読み取れない、System.OverflowExceptionが起こる。 (データは8.012345678901234567890123456 .netのdecimal型の有効桁数に収まる) data provider for sqlserver × data provider for ODBC ○ Visual Studioのデータベースプロジェクトで、 テーブルなどを生成するsqlや実際のMDFを生成することは出来ます。 でも、初期データのレコードをそれに入れるにはどうしたら良いのでしょうか? 単体テスト用の「データ生成計画」を使用すれば、 ランダムな値でレコードを埋めることは可能ですが、 任意の値で作った数レコードを設定する方法はあるのでしょうか? 管理用テーブルに初期レコードを入れたい状況は結構あると思うのですが。 いや、まぁ、そう言われるとそうなんですけれど、 何か美しい方法があるのかなと。 仮にカラム名とかスキーマビューから変更したとき、 初期データスクリプトも自動的にリファクタされたいじゃないですか。 たいていの場合、誰かがツール作ってるな。 開発初期で余裕がある時の息抜きというか腕ならしというかで。 たまに「今後もずっと使える」とかいうのを作るヤツもいるが、 設定項目が多くなりすぎて自前で書いた方が速かったり、 ついでの要望の多さにヘソ曲げて放置になったりしてる。 どうやら、データベースプロジェクトの場合は、 プロジェクトの中のScripts\Post-Deploymentディレクトリ辺りに 初期値をInsertするsqlファイルをいくつでも置いておき、 同じディレクトリのScript.PostDeployment.sqlが最初に実行されるので、 :r .\DefaultValuesUsers.sql のような感じで、それらを呼び出すように書いておくようです。 と、Script.PostDeployment.sqlの最初のコメントにほんの少し書かれてます。 データベースプロジェクトで「配置」を実行したときに何回でも実行されるので、 複数回挿入されることが無いように、 IF NOT EXISTS(SELECT * FROM User WHERE UserID = @User1ID) のような感じでチェックを入れとく必要があります。 http://msdn.microsoft.com/ja-jp/library/ms187993.aspx にて image型は将来削除される予定である、との記述があるため DDL の image の部分を varbinary(max) に置き換えたのですが ADO.NET での new SqlParameter("IMAGE", SqlDbType.Image); のような記述を SqlDbType.VarBinary で max 指定することって出来るのでしょうか? System.Data.SqlTypes.SqlBinary は他の型と違って MaxValue のフィールドが存在しなかったです。。。 質問いいですか? 現在OracleのデータベースをC#から弄ろうとしているのですが Oracleが9iだった場合ODP.netも9iじゃないといけないのでしょうか?(11gじゃだめなんですかね) すれ違いかもしれませんが、どなたか宜しくお願いいたします。 >>241 >>242 ご親切にありがとうございました。返事が遅れてすみません。 やはりOLEDBで行うことにしました。 ODP.netで繋ぐメリットって具体的になんなんですかね? >>243 どっちでもいいならODPのがいいと思うけど・・・ >>243 Oracle => OLEDB => .NET Framework Data Provider for OLEDB Oracle => Oracle Data Provider for .NET 専用ドライバの方がダイレクトに接続できる分効率的 cmd.CommandText = "UPDATE テーブル SET 完了日 = GETDATE() WHERE 設定 IN (@PARAMS)" cmd.Parameters.AddWithValue("@PARAMS", new int[]{1,2,3}); こんなのがすごくやりたいです・・・。 >>247 SQL Server 2008からテーブル値パラメータってのがあるから、それ使えば? >>248 ストアドですか・・・。でも接続先はmdb(2000)。。。(死) パラメータクエリーは、Access 相手でもできるだろが。 mdbにはgetdate()もなかったとおもったがな 対象をちゃんと書かない>>247 が悪い コピペですが・・・・・ ----------------------------------------------------- 深夜のメンテナンス作業で眠くて眠くて、ユーザーの伝票明細テーブルを間違ってTRUNCATEした。 ROLLBACKも効かない。 あせってArcserve開いてテーブルを戻そうとする・・・ログウィンドウを見ると、 バックアップバッチは数ヶ月前から停止したままだった。 頭が真っ白になった。 IDCを出て深夜の自席に戻って、机の中の大事なものをかきあつめてかばんに詰めた。 社員証を課長の机の上に置き、会社を出て、アパートに戻る。 保険証、パスポート、前の年に死んだ愛犬の写真を持ち、始発にあわせて家を出る。 携帯が鳴り始める。何度も何度も何度も。空港につくころには着信が100回を超えた。 電池を抜き、俺は北海道行きの飛行機に乗った。 逃げるなら、なんとなく北、というイメージがあった。 それから3年無為な生活をし、ほとぼりが冷めたころ、北海道の小さな ソフトウェア開発会社に就職した。 経験を買われて、すぐにプロマネになる。 そして、孫請けながら大きなプロジェクトに参加することになり、 キックオフミーティングのために東京へ。 発注元とともに汐留で会議に参加する。 ・・・会議室には、俺が逃げ出した会社の部長と、課長がいた・・・ ふたりとも、会議のあいだずっと、顔を真っ赤にして俺を睨んでいた・・・ こみあげてくる胃痛と嘔吐感に耐え、会議が終わると同時に俺は会議室から逃げ出した・・・ それが、先週の金曜日のこと・・・死にたい・・・ 皆はTableAdapter使ってるのか? 使ってみたけどなんかいまいちじゃ〜 >>254 俺使ってた 型付DataRowは結構便利だった LINQ出たから過去形 TableAdapterもLINQも過渡的な技術で直ぐに過去のものとなる。 やはり、ExecuteReader、ExecuteNonQuery が最強ですな TableAdapterは、紹介見たところで、便利だろうなとは思ったが、 使わなかった。なるべく統一性のある方法でやりたいという考え でやっているので、俺も>>257 のようなやり方でやっている。 LINQは、過去に使いこなされたものを真似して作ったという系統では なく、新しいことをやろうという系統のことなので、言語仕様や 書き方はしばらくの間は変わりそうな予感がするので、手をつけないでいる。 TableAdapterもLINQで読み込みだけさせて更新はExecuteNonQueryで やるのもありかと。 >>257 キャストが要らなくなるならそれでもいいがね >>261 キャストはIDEが教えてくれるので無問題 >>262 だが列名のスペルミスまでは指摘してくれない >>263 テストくらいするだろ〜 TableAdapterでもプロパティ名間違えると駄目だし。 TableAdapterなんてDMLとConnectionをまとめただけのようなもんだろ。 ExecuteNonQueryの結果をそのままTableAdapterにつっこむのに便利 LOOPでSQL吐く代わりに、オンメモリでアクセスしたくなるときは便利やん テーブルロックについて基本的なことを教えてください。 Update とか Merge を投げるクライアントアプリを作ったのですが、 現状トランザクションではなく、単にSQL文を発行しているだけの状態です。 SQL文投げる前にテーブルロックをかける必要はあるのでしょうか? そもそも、トランザクションを使わないDB操作にテーブルロックができるのか 疑問なのですが。 >>269 ロックにもいろいろある 楽観的ロックで検索してみろ オレは何時でも超楽観的ロック。 つまり、ロックなど一切しないw >>269 まず対象のDBMSを特定しないと確実な話はできないんだが 1文のSQLは、その1文だけのトランザクションだと考えていい テーブルロックをかける必要があるかどうかは、SQLが1文かどうかにかかわらない その処理でテーブルロックが必要ならかければいい まあ俺にはSQL1文で明示的にテーブルロックする必要がある処理は思いつかないが 教えてください。 スレ違いだったらすみません。 今度、.net の環境で DB を扱うプログラムを書きます。 基本的にはクライアント側か、クライアントと DB サーバの仲介をする部分を扱うことになります。 DB に関することは教科書レベルでは知っているつもりなのですが、 たとえば効率的な SQL の書き方とか、とにかく実戦レベルで気をつけなければならないことなどは 経験がないためよくわかっていません。 こんな人間が読むのに最適な本をご存知でしたら、紹介をお願いできないでしょうか。 よろしくお願いします。 プログラミングADO.NET 2.0 現場で使えるSQL SqlDataSource の ConnectionString とか SelectCommand をプログラムで動的に 変更することはできるのでしょうか? GridViewにDBを貼り付けて表示させるときに、SqlDataSourceをウィザードで定義 する方法はあるのですが、その設定をプログラムで動的に変更する方法は無いかと 調べているところです。 ご存知の方いましたら教えてください。 >>276 つPage_Load() つか.aspxのソースみれ >>276 >SqlDataSource の ConnectionString とか SelectCommand をプログラムで動的に >変更することはできるのでしょうか? できる。 >GridViewにDBを貼り付けて表示させるときに、SqlDataSourceをウィザードで定義 >する方法はあるのですが、その設定をプログラムで動的に変更する方法は無いかと >調べているところです。 >ご存知の方いましたら教えてください。 http://msdn.microsoft.com/ja-jp/library/system.windows.forms.datagridview.datasource%28VS.80%29.aspx visual studio2008です。 mysqlで、データソース→新しいデータソースの追加→データソースの種類を選択 →データベース→アプリケーションがデータベースへ接続に使用するデータ接続 ここで正確に入れても次のデータオブジェクトの選択で 「選択したデータベースが新しいか、オブジェクトを含んでいません」 になる。 サーバーエクスプローラーのデータ接続では、普通につなげて、中身も見える。 同じように設定しているのだけど、何で差がつくのだろう? 質問する場所違ってたら誘導ください。よろしくお願いいたします。 ちなみに、デザイナで、データセットを編集 を使って、サーバーエクスプローラーのをD&Dすれば普通には使える。 ただ、余計に手間がかかる理由が不明。 DataAdapterでFillしたときに、関連する子テーブルも自動でFillされるんだな。 便利だけど動作が把握し切れん・・・ >>280 GridViewの質問だよ。DataGridViewじゃないよ。 >>283 便利機能のライブラリって、必ずそういう事がつきまとうよな。 で、結局は従来からの面倒だが非常に単純なやり方に落ち着いたりする・・・w Accessのフォームは、非連結フォームに落ち着くよな。 みたいなw DBから、DataTableに読み込んだテーブルがやたらとでかくて、 そのクライアントPCのスペック(メモリ)を超えている場合は、 ADO.NETの範疇でストップをかけることが出来たりするのでしょうか? (DataTableのあるプロパティの値をこうしてたら途中までで自動で 止めるなどの機能はあるのでしょうか) それはVB.NETやOSの範疇だったりするのかな? 途中でストップはないんじゃないの? あらかじめデータが巨大になることが分かっているなら select に where で条件を付けることを必須にするとか、アプリ側の 対処になるような気がする >>288 レスありがとうございます。 テーブルの操作が複雑な場合、サーバやネットワークの負荷を抑える為に、 処理の途中で、一時保存という形でローカルPCにmdbファイルという形で 保存しておいて、それを処理していくというものを作ろうとしたのですが、 その場合、mdbファイルに保存されたテーブルを処理する過程の部分は、 なるべくデータを少なく読み取るように工夫をする事で対処出来ますが、 サーバのテーブルをローカルへコピーする過程の部分で、テーブルが 大きすぎる場合は大丈夫なのかなとか思ったのです。 主キーが無いテーブルの場合は、途中まで読み込んで、クリアして、 また続きからとかの処理は無理ですよね? >>287 俺は使ったこと無いので詳細はわからんが DataAatapterのFillに、 Fill(DataSet, String, IDataReader, Int32, Int32) ってのがある これが開始位置と最大行数指定できるらしい これでなんとかなるんじゃないかな >>290 ありがとうございます。早速詳細を調べてみます。 >>289 その場合だと、DataTableを使わずReaderでループまわして、 直接MDBへ書き込んだ方が効率よくない? >>292 その手がありましたね。ADO.NET使いこなせてなかったので そこまで頭が回っていませんでした。ありがとうございます。 現在VB.NET2005にて データベースの接続及びSQL文発行を行う DLLを作成しており、 接続には『SqlDataReader』を使用しています。 Transactionを指定しない場合に 排他制御がどのように行われているのか、がわかりません。 一切排他が行われないのでしょうか? また、排他制御を実装する場合はどのようにすれば良いのでしょうか? 行いたい制御としては、 @データ取得中(SELECT)にデータ更新を抑止する Aデータ更新中(INSERT/UPDATE/DELETE)にはデータの取得/更新を抑止する です。 >>294 Transactionを明示的に指定しない場合、SQL Serverは自動コミット モードで動作する 自動コミット モードではステートメント単位でトランザクションが自動的に発行される 例) insert insert は概念的には begin tran insert commit tran begin tran insert commit tran と解釈される よって、1つのSQL文の実行中に、まったく同時に他のSQL文を実行したからといって それが行単位である限り、それぞれのSQL文は自動的に発行されたトランザクションで 保護されているため、同時に実行したことが原因でデータを破壊してしまうようなことはない なお、SQL Server のデフォルトの分離レベルはREAD COMMITTEDなので 自動コミットでもREAD COMMITTEDが適用されるはず http://support.microsoft.com/kb/198024/ja http://technet.microsoft.com/ja-jp/library/ms173763.aspx カーソルを使った場合の説明は以下 http://technet.microsoft.com/ja-jp/library/ms190211 (SQL.90).aspx ちなみにトランザクションが必要なのは、複数のSQLの結果をまとめてコミット/ロールバックしたい場合、 複数のINSERT/UPDATEの途中でSELECTされたら困る場合、あるいは性能を意識する場合など その場合の記述方法はデータベースの入門書を読んで勉強してくれ すみません、質問いいですか?環境はVS2008pro C# SQLServer2005EEです。 SQL分でLIKE抽出するときなのですが、%っていうのは「なくても」or「何が何文字あっても」って感じですか? ワイルドカード文字数を指定してLIKE抽出したい場合*を使うのでしょうか? 又、*は「とりあえず何らかの文字が1文字以上ある」なのでしょうか? やりたいことは (0は何らかの数字/A,Bはアルファベットが入ります) 000A000 000B000 000A000B 000B000A の中から4文字目にBがくるものだけ抽出したいのです。 LIKE %B% では000A000Bも拾ってしまいます。 この場合*B*でいいのでしょうか? (正規表現も試しましたがかなり遅い感じを受けましたので出来れば避けたいです) よろしくお願いいたします。 >>297 ありがとうございました! 一文字ワイルドカードとして_を使っては見たのですが まったく意図する結果が得られなかったので*なのかな?と思っていました。 LIKEのターゲットがCHAR(8)なのでこれが原因みたいですね。 read.cgi ver 07.5.5 2024/06/08 Walang Kapalit ★ | Donguri System Team 5ちゃんねる