ADO.NETの質問・雑談スレ2
ADO.NETに関する質問・雑談・評価 etc 何でもどうぞ。 前スレ ADO.NETの質問・雑談スレ http://pc11.2ch.net/test/read.cgi/db/1104630889/ >>128 ここADO.NETの質問・雑談スレだし ま、しつこ言わいとれれば実際そのとおりだが いまの流れは、 >今の非接続型、接続型の区別にどんな意味があるんだ? に対して、 >ネットワークの負荷だろ ときて >ネットワークの負荷に差がでる理由を教えてくれ となり>>126 へ じゃ、俺もこの議論に参加してみる。 接続型と非接続型の違いは、「DBに接続し、データの取得や更新を する過程の部分」には無く、「取得したデータをローカルのメモリに 保存してるかどうか」の部分にあると思う。 だから、DataSetを使っていると非接続型、DataReaderは接続型 という風に分類されている。 前スレの最後の方で語られていた事で、>>2 の4.にまとめられている ことだけど、「DataReaderを使いたがるスタイル」は、ADO房や VB6プログラマに限ったことじゃないような気がする。 java(JDBC使い)から.NET開発に移ってきた人も、以前までやっていた ものと似たようなスタイルでコーディング出来るDataReaderを 使いたがるんじゃないかな。 DB操作用のモジュールで、一般的な設計に近いものがDataReaderで ある為、他の人にとって読みにくい!みたいな、問題が起きるような 気がする。 http://www.shoeisha.com/mag/dotnet/pdf/870406/dotnet0406_153_Oracle.pdf この文書には、「非接続型=DataSetクラスを使っていること」とあるな。 「接続型」、「非接続型」の用語の理解はこれでいいんじゃないの? ネットワークの負荷の違いは、そのアプリケーションの組み方次第なので、 一概には言えない。(その人がイメージしているアプリの形によって差が でるので、「こちらの方が負荷が違う」ということが多い) 「非接続型=DataSetクラスを使っていること」は良いとして、 「接続型=DataSetクラスを使っていないこと」ではないと思うんだな。 「接続型」と積極的に言えるのはせいぜいADOなどで更新やスクロール可能な 結果セットを使った場合だと思う。 CommandやDataReaderクラスは非接続型か接続型という分類じゃなく、 そられを実現するための基本的なADO.NETデータプロバイダのファンクションそのものであると考えるべき。 ADO.NETを解釈すると、データプロバイダ(ドライバ)+DataSetフレームワークというべきもので あるが、たびたびデータプロバイダのみをADO.NETと呼んだりするのでややこしいい。 ADO.NET Entity Frameworkでもデータプロバイダは共通なんだよね。 >>132 それ、昔の.NETマガジンの記事だな その記事みると、接続型はサーバカーソルのようにみえるな まあ、対象がORACLEなんで若干の違いがあるのかもしれないが、 ADO.NETではサーバカーソルは(ADO.NETの機能としては)サポートしてなくて DataReaderでさえサーバカーソルは使わないらしいが... その記事でも、接続、非接続の区別が大事だって書いてあるなぁ 「非接続型=DataSetクラスを使っていること」が定義になるだろうってことに反対はしないが >>130 がいうように、、「取得したデータをローカルのメモリに保存してるかどうか」が大事なとこなんだろうな 結果としてDataSetを使ってるというだけで だから>>133 の言うように>「接続型=DataSetクラスを使っていないこと」ではないと ただ、その定義にしたがって考えれば、 「ローカルのデータセット更新中も接続を保持する非接続型がある」ことになるんだが だったらその定義や、接続、非接続の区別が重要だとは思えないんだよな 接続型か非接続型かじゃなくて、コネクションをオープンしたままなのかクローズしてあるのか、 サーバ側のロックを保持してるのかどうかが大事なんだと思うんだが... 非接続型って言うと、どうしてもサーバ側のロック持てないイメージがあるんだ 名前がよくないのかもしれないな。これ、英語ではどんな単語で表現されてるんだろうなぁ 残念ながらそのものズバリconnectionless 俺は、「非接続型」というのは、DataSetをアピールするためのキャッチコピーの ようなものだと思ってるんだけどな。そもそも、DB接続プログラミングに関して そのような用語や概念は無かったのだから、DB設計をしたり実装したりする 時においてはさほど重要ではないと思う。 接続型とか非接続型ってのは、MySQLのC APIで言えば、 それぞれ、mysql_store_result()とmysql_use_result()でしょ? >>137 いい事いうじゃねえか。 出来るんだな? 今すぐ頼むぞ。 >>137 MySQLよく知らないんで、その違いを説明してくれないか ADO.NETのスレでMySQLに例える意味がわからんが javaのWebアプリ開発経験者です 今回、初のASP.NETの開発のため調査しています。 いまのところ、ASP.NETのDB処理は「非接続」で実装(javaと同じような) すればよいという認識ですが、正しいでしょうか? そもそも、このスレは、ASP.NETは考慮せずに、 Windowsアプリのみを想定しているのでしょうか? >>2 の「前スレの流れ」はASP.NETとWindowsアプリの区別は無いのでしょうか 状況により使い分ける。 例えば接続型のDataReaderの方がパフォーマンスは良い。 しかし、順方向への読取専用にしか使えないので、 例えばGridViewのページングを使いたいような場合には向かない(できない)。 >>142 すぐ上で接続型と非接続型に対する議論が白熱してるw で、俺はjavaはわからんのだが、javaと同じような非接続の実装ってのはどういうもんなんだろ >>131 なんかが言うには、javaだとDataReader使うようなスタイルになるみたいだけど、 それなら分類的にはどっちかっていうと接続型だと思うが... まあ、少なくともDB周りにおいてはその区別は重要ではないという流れではあると思う WebアプリかWindowsアプリかについては、俺の私的意見ではあるが、ADO.NETは Webアプリ的思考をWindowsアプリにも適用する方向に向かって進んできたので Webアプリにおいてはあまりその違いを重要視する必要がないと思う Webアプリなら特性上、楽観的ロックでコネクションは即時解放ってスタイルにならざるをえないと思うが まあ普通にADO.NET使って作ってればそうなってると思うw >>142 文面からすると、「javaは非接続型で実装するスタイルがメインである」と 読み取れるのだが、JDBCの場合、テーブルデータをローカルメモリに 保存する機能のクラスはないのだから、「javaは接続型」だと思うのだが。 javaであなたが実際に実装する際に使っているライブラリやクラス名を 教えて欲しい。(O/Rマッピングあたりなのかな?) このあたりがはっきりしないとレスもしようが無いので。 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の中に入れてしまっている 可能性などもあるので、具体的にどういうプログラムを書いているのか、 現状は何秒かかっているのか、何秒くらいにしたいのか、などを 書かないと話はすすまないんじゃないかな。 read.cgi ver 07.5.5 2024/06/08 Walang Kapalit ★ | Donguri System Team 5ちゃんねる