Accessデータベース一覧

タグの編集
投稿者 Tさん  (社会人) 投稿日時 2023/8/28 13:00:31
vb.net .netFramework 4.8
でwindowsフォームアプリを作っております。

そのなかで
Accessのデータベースに接続しデータベース一覧を取得しようとしています。
GetSchemaで第一引数を"Tables"だけでは取得できるのですが、
この中からSYSTEM TABLEを除外するために第二引数を設定するとうまくいきません。

下記のコードで実行すると
取得できず、どこがおかしいか誰かご教示頂きたいです。

独学ど素人なので色々おかしな点あると思いますがよろしくお願いします。

Property DBpath As String
Property DBID As String
Property DBPW As String
Property DataTable As DataTable

Function AllTableGet() As Boolean
 AllTableGet = False
 Try
  '接続文字列セット
  Dim odbcdrv As String = "Driver = {Microsoft Access Driver (*.mdb, *.accdb)}:DBQ=" & DBpath & "; Uld=" & DBID & "; Pwd =;" & DBPW 
  Using cn As New OdbcConnection (odbcdrv)
   cn.Open()
   DataTable= cn.GetSchema("Tables", New String(){Nothing. Nothing. Nothing. "TABLE"})
  End Using
  AllTableGet = True
 Catch ex As Exception
 End Try
End Function
投稿者 魔界の仮面弁士  (社会人) 投稿日時 2023/8/28 14:27:26
> データベース一覧を取得しようとしています。
「データベース一覧」…?
Access のデータベースって、*.accdb や *.mdb ファイルのことですよね?

もしかして、「テーブル一覧」のことですか?

> New String(){Nothing. Nothing. Nothing. "TABLE"}
「.」ではなく「,」ですよね。


> Using cn As New OdbcConnection (odbcdrv)
あれ。Access Database への接続なのに、
OleDbConnection ではなく、OdbcConnection で繋いでいるのですね。珍しい。

> Dim odbcdrv As String = "Driver = {Microsoft Access Driver (*.mdb, *.accdb)}:DBQ=" & DBpath & "; Uld=" & DBID & "; Pwd =;" & DBPW
接続文字列の文法が間違っています。
「:」ではなく「;」ですよね。

そもそも、そのような文字列埋め込み処理ではインジェクション問題を引き起こしかねません。
OdbcConnectionBuilder や
OleDbConnectionBuilder を用いて構築すべきです。

Dim builder As New OdbcConnectionStringBuilder()
builder.Driver = "Microsoft Access Driver (*.mdb, *.accdb)"
builder("DBQ") = DBpath
builder("Uid") = DBID
builder("Pwd") = DBPW
Using cn As New OdbcConnection(builder.ConnectionString)



> この中からSYSTEM TABLEを除外するために第二引数を設定するとうまくいきません。
TABLE_TYPE 条件は指定できません。

Tables スキーマで指定できる条件は、
「TABLE_CAT」「TABLE_SCHEM」「TABLE_NAME」の 3 条件だけです。

TABLE_TYPE 条件が必要な場合は、Linq もしくは DataView で絞りこみましょう。

DataTable = cn.GetSchema("Tables")
DataTable.DefaultView.RowFilter = "TABLE_TYPE<>'SYSTEM TABLE'"
投稿者 Tさん  (社会人) 投稿日時 2023/8/28 15:02:27
魔界の仮面弁士さんありがとうございます。
いろいろと転記ミスしてました。

>Access Database への接続なのに、OleDbConnection ではなく、OdbcConnection で繋いでいるのですね。珍しい。
珍しいんですね。あまり良くわかっておらずネットで見つけた方法でやっていました。


>OdbcConnectionBuilder やOleDbConnectionBuilder を用いて構築すべきです。
そんなのですね。ご教示頂いた方法にします。

> TABLE_TYPE 条件は指定できません。
>Tables スキーマで指定できる条件は、「TABLE_CAT」「TABLE_SCHEM」「TABLE_NAME」の 3 条件だけです。
>TABLE_TYPE 条件が必要な場合は、Linq もしくは DataView で絞りこみましょう。
TABLE TYPEはしていできないのですね。
勉強になります。ご教授頂いた方法で行います。





投稿者 魔界の仮面弁士  (社会人) 投稿日時 2023/8/29 13:32:42
>>TABLE_TYPE 条件が必要な場合は、Linq もしくは DataView で絞りこみましょう。
> TABLE TYPEはしていできないのですね。
OleDbConnection であれば、TABLE_TYPE 条件で検索できます。

"Table" スキーマを指定する場合、
OdbcConnection では 3 条件 (database / owner / table name)
OleDbConnection では 4 条件 (catalog / schema / table name / table type)

とはいえ前回の回答の通り、取得後に絞り込んだ方が融通が効くかと思います。

Dim builder As New OleDbConnectionStringBuilder()
builder.Provider = "Microsoft.ACE.OLEDB.12.0"
builder.DataSource = "C:\…\Database1.accdb"
'builder("User ID") = … 
'builder("Password") = … 
'builder("Jet OLEDB:Database Password") = … 
Using cn As New OleDbConnection(builder.ConnectionString)
    Dim restrictions(3) As String
    restrictions(3) = "TABLE"
    cn.Open()
    DataGridView1.DataSource = cn.GetSchema("Tables", restrictions)
    cn.Close()
End Using



Connection オブジェクトによって、取得後の列名が異なる点にも注意してください。

https://learn.microsoft.com/ja-jp/dotnet/framework/data/adonet/odbc-schema-collections
https://learn.microsoft.com/ja-jp/dotnet/framework/data/adonet/ole-db-schema-collections
https://learn.microsoft.com/ja-jp/dotnet/framework/data/adonet/sql-server-schema-collections
https://learn.microsoft.com/ja-jp/dotnet/framework/data/adonet/oracle-schema-collections
投稿者 Tさん  (社会人) 投稿日時 2023/9/14 20:24:32
魔界の仮面弁士さんありがとうございます。
いろいろ勉強になりました。
ご教示頂いた内容を試してみます。