ADO.NETの質問・雑談スレ2
ADO.NETに関する質問・雑談・評価 etc 何でもどうぞ。 前スレ ADO.NETの質問・雑談スレ http://pc11.2ch.net/test/read.cgi/db/1104630889/ ADO.NET単体では MDBファイルの新規作成はできないのでしょうか? COMを使えばできるのは解ってます。 ADOの時代からADOX使わないと無理だったんで、無理だと思う ADO.NETはあくまでも既存のDBに接続するためのものってことだな >>144 >>145 142です。ああああ、ごめんなさい。 ご指摘の通り、javaは「接続型」です。記入間違いです。 混乱させてしまいました。 >>143 ですよね。 GridViewのページングのためしか、「非接続型」は使えないきがする。 >>144 >すぐ上で接続型と非接続型に対する議論 この論議がWindowsアプリを前提にしているのかなぁ? と思ったので質問しました。 >Webアプリなら特性上、楽観的ロックでコネクションは即時解放ってスタイル ですよね。そうかなと思ってたので、安心しました。 >>145 ちなみにjavaのDB処理は、DbUtils好きです。 O/Rマッピングは、わかりにくいのであまり好きじゃありません。 今回のASP.NETの開発は、基本は「接続型」で GridViewのページング機能を使うなら「非接続型」使用します。 ありがとうございました。 >>146 話の整理をする意味合いでの意見だが、 ファイル操作はADO.NETの範囲ではない。 >>149 MDBファイルの新規作成を、ファイル操作って言っちゃうと ちょっと議論がずれるとおもうぞ MDBファイルの新規作成=JetでのDBの新規作成 って意味だと思うんだ Jetが(実際は無理なんだが)create databaseとかのSQLでMDB作れるなら、 ADO.NETからSQL発行すれば可能なんだろうけど、その場合でも それはADO.NETの守備範囲ではないと思うんだ MDBファイルの作成であれば、ファイル操作でやるしかないでしょ。 ひな型となるものを作っておいてコピーするとか。 そもそもMDBは、それに接続してDB作成とかいう概念がないはず。 DB が SQL Server であれば、作成は可能だが。 http://support.microsoft.com/kb/305079/ja >>151 ADOX使えばできるだろうという話はまあ置いといて ファイル操作がADO.NETの範囲外なのは当然なんだよ ただ、MDBの新規作成は、元来はファイル操作じゃなくてDBMS操作だろう、ってことだ >>150 は、DBMS操作は(たとえSQL発行で実現できたとしても)ADO.NETの範囲外だろう、と主張してる 俺なりのjava(JDBC)と.NET(ADO.NET)の比較 ・接続方式のプログラミングは、概念は同じ。 DBに接続して、SELECTして・・・ ・非接続方式はADO.NETだけ 格納用に配列を準備してそれに代入して・・・という処理を 書かなくて済む分、DataTableは便利。 ・ADO.NETは選択肢が無い O/Rマッピングあたりになると、javaは選択肢がたくさんあるが、 .NETだと、LINQしかない。 これはプロジェクトの上でメリットにもデメリットにもなりうる。 他と比較しながら、ADO.NETについて見てみるのもいいかも。 PHPでのDB接続の場合は、取得結果を連想配列に格納となっているようだ。 ただし、接続先のDBが限定されてるようだけど。 ADO.NETのDataTableは連想配列ではなかったり、それに簡単に格納出来なかったり する部分が不便だけど、PHPみたいに接続DBの種類を限定はしていないところは 良いところだな。 mysql_fetch_array http://bg.pi-ppi.com/page/n01/000152.html >>153 .netもnhibernateとかs2dao.netとかあるだろ javaの移植だけど ibatis も忘れんでくれーーー #まだ使ったこt無いんだが >>154 DBI::DBDだとみんな、連想配列だと思うのだが ちょっと念のために一つ確認。 現状では、ADO.NETでDB接続し、テーブルデータ取得時に、 一発で連想配列に格納する事って出来ないよね? DataTableは連想配列じゃないし。 連想配列のように扱うこともできると思うけど、それじゃいかんの? DB接続に関するモジュールが提供する機能となると、このくらいで終わり なのかなぁ?複数テーブルをJOINした場合の更新のサポートとか、 ちょっと複雑なクエリを使って集計する必要がある場合、簡単に 抽出が出来るとかそういうのがあってもよさそうに思うんだけど。 >>複数テーブルをJOINした場合の更新のサポート 複数テーブルのテーブルロックになっていいの? #行ロックじゃなくって >>ちょっと複雑なクエリを使って集計する必要がある場合 複雑なクエリで集計->複雑な条件で抽出&集計 になると思うのだが? 大量データのINSERTについて質問なんですが、10万件のデータをなるべく早く生成したく、下記のようなコードで実行してみましたが 想像を超えるほどに遅くかなり間がかかってしまいます。 DbProviderFactory objProviderFactory = DbProviderFactories.GetFactory("System.Data.SqlClient"); using (DbConnection objConnection = objProviderFactory.CreateConnection()) { objConnection.ConnectionString = "Data Source=localhost;Initial Catalog=testdb;Integrated Security=SSPI"; objConnection.Open(); using (DbTransaction objTransaction = objConnection.BeginTransaction()) { for (int i = 0; i < 100000; i++) { using (DbCommand objCommand = objProviderFactory.CreateCommand()) { objCommand.Transaction = objTransaction; objCommand.Connection = objConnection; objCommand.CommandText = "INSERT INTO testtable (filename) VALUES(@val);"; DbParameter param1 = objCommand.CreateParameter(); param1.ParameterName = "@val"; param1.DbType = System.Data.DbType.String; param1.Value = System.IO.Path.GetRandomFileName(); objCommand.Parameters.Add(param1); objCommand.ExecuteNonQuery(); } } objTransaction.Commit(); } } なんとなく、Transactionの使い方を間違えてる気がするのですが。 開発は.NET 3.5 & SQL Server 2008 Expressで行っています。 10万回もCreateCommandして 10万回もパラメータ生成してりゃ遅くもなるわな >>175 CreateCommandとパラメータ生成をforの外にだせ つか、本気で言われないとわからないならプログラマ向いてないぞ まあ、それでも遅いってなら、バルクインサート検討しないと無理かも知れん >>176 まじで?じゃあコード書いてみなよ できるもんならね! ふふん / ̄ ̄ ヽ, / ̄ ̄ ヽ, / ̄ ̄ ヽ, / ', / ', / ', {0} /¨`ヽ {0} {0} /¨`ヽ {0} {0} /¨`ヽ {0} l トェェェイ ', l トェェェイ ', l トェェェイ ', ノ `ー'′ ', ノ `ー'′ ', ノ `ー'′ ', /,, -ー 、 , -‐ 、 /,, -ー 、 , -‐ 、 /,, -ー 、 , -‐ 、 ( , -‐ '" ( , -‐ '" ( , -‐ '" ))) `;ー" ` ー- -ー;'" `;ー" ` ー- -ー;'" `;ー" ` ー- -ー;'" l l l l l l なんかくだらん煽りがおおいのは新年度だからか? >>176 実験した VS2008+SQL2000 ベンチの公開は禁止されてたような気がするので具体的な数字は伏せる 処理時間で96%ぐらいになった。つまり4%ぐらい高速化された 思ったより差が出なかった >>168 は想像以上に遅かったといっているが、 俺の想像以上に早かったw パラメタにサイズ設定して、objCommand.Prepare追加したらさらに数%早くはなったが 10秒程度のオーダーで数%だから、誤差に近いかもしれんな 偉そうに間違えるのってかっこいいね。 あこがれる。 もっと速くってことなら せっかく2008使ってるんだし ストアドとSQL CLR使ってみれば? かなり速くなると思うけど 俺は168じゃないぞ。念のため >>179 少なくとも確実に数%早くなってるぞ。間違ってるとはいえない つか役に立たんレスとか煽りとかいらない >>180 10万回CreateCommandした場合とPrepareした場合とで数%の違いなんで、 ストアドにしても大差はないと予想した。SQLの解析時間は数%ってことだから 処理時間のほとんどはinsert文の実行時間なんじゃないかな うちの環境ではSQL CLRは試せないが、バルクでインサートしないと 結果は大差ないと予想。だれかモノ好きが実験してくれw まあ、ADO.NETは結構速いと俺は思ったぞ。SQL Serverに限ればかも知れんが >>180 ストアドとはストアードプロシージャーのことでしょうか? あまりよくわからないので、多少は使い慣れたC#から、とおもったのですが。 お騒がせしましたが、たかが10万件ですし、手入力で解決しました。 >>181 つか役に立たんレスとか煽りとかいらないからまじで 質問です。 表示専用にしたDataGridViewに表示中のDataTableに対して行を追加するのに、BindingSource.AddNew()とEndEdit()で 追加して、ソートしてあると追加行は自動的にしかるべき位置に並べ替えられますが、 その後、追加した行が選択されず、その1行下が選択されてしまいます。 ちなみに、最下行に新規行が追加されるときだけは新規行が選択されます。 BindingSource.Position自体が1行下を指す値になっていました。 PositionChangedイベントを見てみると、EndEdit()後に一度Positionが 新規行の値になり、直後に1行下に変わって、都合イベントが2回起こります。 DataTableを型指定しない最小限のもので試したり、DataGridやDataViewを 使っても同じ現象が出ます。どうも、CurrencyManagerからして そのような動きをしているようです。 選択行が追加前と変化しないとかならともかく、微妙に1行ずれとかだと 困ってしまいます。なんとかならんでしょうか。 >>187 俺はこれまで、そういった問題に直面したことはないが、 そこまで解決がうまく出来ない場合は、追加する前にあらかじめ 主キーとなるデータをローカル変数に保存しておいて、 あとで選択し直すという方法をとってみたらどうかなと 思うが、そのあたりは試してみたのかな? データセットのデザイナ、便利で助かっているのですが、 実際のテーブルの定義を変更した時にどうやってデータセットのほうに 反映させればいいのかわかりません。 テーブルの列の追加や削除、NOT NULL の変更などが発生した際 皆さんはどのように対応していますか? >>189 データセット作り直すしかないんじゃないかと>定義ファイル作って差替え #それが嫌で使ってない 型指定されたデータセットって半分使い捨ての気分で 使わないとイライラとすることが多いように思う。 コーディングが楽になるとか、いくつかメリットはあるけれど。 だから、かなり単純なテーブルのデータを読み込む場合など の時にしか使わないな。俺は。 >>189 たとえばテーブルに新たに列を追加した場合、 TableAdapter構成ウィザードのクエリビルダで 追加した列を選択して再構成すれば大丈夫みたい。 >>182 ストアド苦手っていうプログラマでろくなヤツ見たことないな。 そういうやつに限ってメンテしづらいし、 後々、致命的な性能問題起こすプログラム書きやがる。 >>29 超亀だけど、あの本読まずに何を読む って気がするんだけど VB+C#対応だから、お買い得だと思う M$の言語を使おうというのならば、公式図書とMSDNはおさえとかないと いけない。その道を通らずに習得するのは無理でしょ。 最初からコーダー目指すのならば、「ここはこう書くんだ」みたいな 形式の適当な研修を受けるだけで十分かもしれないが。 >>193 まぁ まともなSQLかける奴も少ないけど #最近 少しはましになったw LINQとか、型指定されたDataSetとか、CommandBuilderとか、 SQL文を自分で細かくかかなくても自動生成されるよっていう のがあるけれど、俺はやはりSQL文を自分で書くスタイルの方が いいな。このほうがパフォーマンスが大きく変わるわけでも ないけれど、他の言語(javaやPHPなどADO.NETを使わない場合) での開発も視野に入れると、ある程度似たようなコーディング スタイルの方がいいと思うから。 プログラミングMicrosoft ADO.NET2.0 は MSDNライブラリの内容を書籍にしたような感じだから 紙じゃなくてもいいのなら MSDN ライブラリで十分かもしれん。 MSDNライブラリよりは解説が多い分わかりやすいかもしれんが。 リファレンス部はそうだけど、それ以外の部分は MSDNライブラリを探しながら体系的に見ていく事が 初心者にできるか って事だと思うが #最低限の知識がないまま、いきなりMSDNライブラリを読む #というのは、自分的には時間がもったいないと思う ReportViewerコントロール用のレポートファイル( .rdlc )のデザイナでの作成方法について色々解説してあるページとか参考書ってないでしょうか。 レポートウィザードで作れるピボットテーブルをベースに色々と追加したい要素があるんですが、どうやりゃ良いのかいまいちわからない。 一応、やりたいことは今年度のピボットテーブルに前年度の合計とか、前年度比とかの行とか列を追加することです。 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のがいいと思うけど・・・ read.cgi ver 07.5.5 2024/06/08 Walang Kapalit ★ | Donguri System Team 5ちゃんねる