質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Access

Accessはマイクロソフトによるリレーショナルデータベース管理システムです。オブジェクト指向のアプリケーション作成に対応しており、テーブルや編集をはじめ、クエリ生成、入力フォーム作成、レポート作成など一通りの機能を備えています。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

Q&A

解決済

3回答

5602閲覧

至急お願いします。AccessDBにアクセスをして、sqlで抽出した件数と検索データを取得したい

DENQ

総合スコア19

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Access

Accessはマイクロソフトによるリレーショナルデータベース管理システムです。オブジェクト指向のアプリケーション作成に対応しており、テーブルや編集をはじめ、クエリ生成、入力フォーム作成、レポート作成など一通りの機能を備えています。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

0グッド

1クリップ

投稿2016/07/15 01:45

編集2016/07/15 02:27

いつもお世話になります。
環境
windows 8.1
.Net Framework 3.5
Visual Studio 2010

AccessDBにアクセスをして、sqlで抽出した件数と検索データを取得したいです。
Accsessにあるデータは

tableA
IDNO CYCLE BTYPE TIMESTAMP BinaryData の4カラムです。

まず最初に検索して、抽出された全体の件数を取得したいと思ってます。
その上でバイナリデータの読み込みがしたいです。

OleDbConnection conn = new OleDbConnection();
OleDbCommand comm = new OleDbCommand();
conn.ConnectionString = @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + inputFilePath + FileName;

comm.Connection = conn; comm.CommandText = "select count(*) from tableA where tableA.CYCLE = (SELECT MAX(tableA_1.CYCLE) FROM tableA AS tableA_1 WHERE tableA.IDNO = tableA_1.IDNO)"; comm.Connection = conn; OleDbDataReader reader = comm.ExecuteReader(); -この部分で表示件数を取得したいです。- while (reader.Read()) { }

このまま実行するとsql発行時に相当な時間がかかります。件数が多いため。
インデックスを付与すればいいのですが、そのやり方がわかりません。
まずはインデックスを付与してセレクト文を流して、その件数を取得できればと思っております。
件数が多いのでできる限り早い検索ができるとうれしいです。
お手数をお掛けしますが、よろしくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

ベストアンサー

同じ質問ですね。

投稿2016/07/15 02:29

Zuishin

総合スコア28656

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

DENQ

2016/07/15 02:32

同じですが、インデックスの付与の仕方がC#上ではわからなかったので再投稿しました。
Zuishin

2016/07/15 02:34

アクセスでつけたらいいのではないですか?
DENQ

2016/07/15 02:38

アクセスのデータはお客様から頂いてそのまま使用するので、アクセス側で付与するのはできない状況です。
Zuishin

2016/07/15 02:40

その理由だと、C# でもできません。テーブル情報を書き換えることになります。 頂いたデータをコピーして、それを使うということもできませんか?
DENQ

2016/07/15 02:46

となれば、一度データセットに入れた方が早いでしょうか? コピーはできますが、毎回コピーを取得してインデックスを付与してという行程を省くためにC#で付与できれば思っております。
Zuishin

2016/07/15 02:50

本当に件数のために時間がかかっているのであれば、データセットに入れて速くなるとは思えませんが、一度やってみてはいかがでしょうか? ここでは見つかっていない他の問題が解決して速くなるかもしれません。
Zuishin

2016/07/15 02:56

いや、そうですね。カウントとデータ取得と同じ検索を二度することで時間がかかっているとするなら、順序を変えて、検索したデータをデータセットに入れて取得し、その行数を数えることで速くなるかもしれません。
DENQ

2016/07/15 03:00

一度試してみます。
Zuishin

2016/07/15 08:46

この場合の要件をもう一度確認したいのですが、こういうことですよね? ・アクセスデータベースの形で客からデータをもらう ・そのデータは変更不可 ・読み出すのは一度きり C# で SQL を使ってインデックスをつけることはできます。 できますが、それにはやはりそれなりの時間がかかります。 検索時に時間をかけないよう、あらかじめ時間をかけて目次を作っておくのがインデックスを作る意味だからです。 何度も検索をするのであればする意味はありますが、いわば使い捨てとも言えるこの状況ではどうでしょうか? アクセスだし、インデックスついてないし、時間がかかるのは仕方がないと私ならそう考えて、空いている PC に作業をさせながら別のことをするかもしれません。 あるいは、この状況では顧客も不便であろうと思えば、インデックスについて説明して、あらかじめコピーしてインデックスをつけておいたデータベースで実演してみせ、互いの利益をはかるかもしれません。 また「アクセス 遅い」で検索するとスピードアップのヒントがみつかるかもしれません。 https://www.google.co.jp/search?q=access+%E9%81%85%E3%81%84
guest

0

そもそもかもしれませんが、件数を取得したい理由は何でしょうか。
それによるんですが、真正直に「count」を取得する必要がどうしてもあるのでしょうか。

例えば質問にある最後の while のループ内でカウントアップすれば、件数は取得できますよね。

処理の順序としてそれでは遅い、のでしょうか。

投稿2016/07/15 03:30

kaz.Suenaga

総合スコア2037

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

DENQ

2016/07/15 03:53

全体の件数を分母にして処理の状況を表示するためです。while 文の中で処理をしていくので中に入る前に分母を取得したいのです。
kaz.Suenaga

2016/07/15 04:23

すると正攻法ではSQL自体の性能をよくすることになるかと思います。 1度コーディングから離れて、accessのクエリで同じ意味となる結果を得るSQLを試行錯誤してはいかがでしょうか。
Zuishin

2016/07/15 04:30

select count(*) from tableA where tableA.CYCLE = (SELECT MAX(tableA_1.CYCLE) FROM tableA AS tableA_1 WHERE tableA.IDNO = tableA_1.IDNO kaz.Suenaga さんならどうお書きになりますか?
kaz.Suenaga

2016/07/15 05:11 編集

ここに示されている条件だけであれば 提示されているものか、LEFT JOINに置き変えたもの、でしょうか。 後斜め読んでいるので正確に要件を把握していませんが、このSQLなら結局IDNOをグループ化したCOUNTと一致する気もします。 データの状態にもよりそうな気がします。 また別のデータで自ずとその件数と一致するはずのデータとかないのかなあ、と思いました。 あ、あとcount(*)よりもcount([インデックスがはられた列名])が早い、とかのtipsもありましたね。
DENQ

2016/07/15 05:01 編集

インデックスは張られていないですね。なのでアスタにしました。 一応、datasetに格納してrowの数を取得できればと考えています。 ただ、またここで少し止まってます。 data.FillSchemaの部分でアイテムがないと言われます。 赤ペンお願いします。 OleDbConnection conect = new OleDbConnection(); OleDbCommand comand = new OleDbCommand(); conect.ConnectionString = @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + inputFilePath + FileName; conect.Open(); System.Data.OleDb.OleDbDataAdapter data = new OleDbDataAdapter("select * from Table_A where Table_A.CYCLE = (SELECT MAX(Table_1.CYCLE) FROM Table_A AS Table_1 WHERE Table_A.IDNO = Table_1.IDNO", conect); comand.Connection = conect; comand.CommandText = "select * from Table_A where Table_A.CYCLE = (SELECT MAX(Table_1.CYCLE) FROM Table_A AS Table_1 WHERE Table_A.IDNO = Table_1.IDNO)"; comand.Connection = conect; OleDbDataReader reader = comand.ExecuteReader(); DataSet dtSet = new DataSet("Table_A"); data.FillSchema(dtSet, SchemaType.Source, "Table_A"); DataTable dtTable; dtTable = dtSet.Tables["Table_A"]; int fileSize = dtTable.Rows.Count; よろしくお願いします。
kaz.Suenaga

2016/07/15 05:09

すみませんが、この手はコメントに書かないで質問を編集して追記していただけますか。 他の方からの回答も得られますよ。
DENQ

2016/07/15 05:15

(SELECT MAX(Table_1.CYCLE) FROM Table_A AS Table_1 WHERE Table_A.IDNO = Table_1.IDNO)←かっこがなかったみたいです。 すみませんでした。
DENQ

2016/07/15 05:17

エラーはなくなりましたが、dataTableの件数が0ですね…。
Zuishin

2016/07/15 05:19

Fill() しましょう。
DENQ

2016/07/15 08:21

Fill()にしたのですが、びっくりするぐらい思いです。
Zuishin

2016/07/15 08:25

だめでしたか。
DENQ

2016/07/15 08:48

ですね。何かいい解決策を見出したいのですが...。 なにかございませんか?
DENQ

2016/07/15 09:26

カウントを取らないでもいい仕組みにしました。 分母を表示せたかっただけなので、それで処理が重くなるのは本末転倒ということで while文で回ってる間の数を処理数として表示するようにしました。 根本的な解決とはなりませんでしたが、一応締め切らせてもらいます。 ありがとうございました。
guest

0

先にIndex文発行するだけなのでは?
CREATE INDEX ステートメント (Microsoft Access SQL)

投稿2016/07/15 02:50

Mr_Roboto

総合スコア2208

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

DENQ

2016/07/15 02:55

アクセス側で先にインデックスを作成するということでしょうか? それともC#上で発行できるのでしょうか? 基本的にアクセス側ではインデックスの付与はしたくなく、C#上でできればと思っております。
Zuishin

2016/07/15 02:59

C# を使っても、インデックスを作成すると、アクセス側のテーブル構造は変わります。先にバックアップを取ってください。
Mr_Roboto

2016/07/15 02:59

C#側からIndex文発行は、できると思いますよ。 アクセス側と言ってるのが何を表しているのが不明ですが IndexはDBのテーブルに付くものなのでアクセスのテーブルを変更できないのであれば原理上不可能だと思います。 C#上というのであれば、全部引っ張ってきてメモリーの中なり展開するとかしか考えられませんが、そのあたりの要件をはっきりさせてみては?
Zuishin

2016/07/15 02:59

という話を先ほどしました。
Mr_Roboto

2016/07/15 03:02

なるほどw もとのテーブルごとテンポラリテーブルにコピーしてからインデックス貼るとか どっちにしても最初からインデックス貼ってないかぎりあまり改善できそうにないですが。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問