Accessのテキスト型とメモ型の識別

解決


えどたつ  2011-01-10 11:44:33  No: 147285  IP: [192.*.*.*]

失礼します。
VB2005で、Access2003のテーブルをDataTableに取得しました。
各ColumnのDataTypeを取得すると、Accessのテキスト型もメモ型も同じSystem.Stringと表示されます。

テキスト型とメモ型によって処理を分けたいので、識別したいのですが、いい方法が見つかりません。

どのようにすれば、見分けがつくのでしょうか?
よろしくお願いします。

編集 削除
魔界の仮面弁士  2011-01-10 23:15:12  No: 147286  IP: [192.*.*.*]

DataColumn.DataType が表すのは .NET 側のデータ型であって、
DB 側のデータ型ではありませんしね。

> テキスト型もメモ型も
両者の違いとしては、最大文字列長の違いという事になりますが、
テーブル構成を取得する意図であれば、
  System.Data.OleDb.OleDbDataReader.GetSchemaTable メソッド
  System.Data.OleDb.OleDbConnection.GetOleDbSchemaTable メソッド
  ADODB.Connection.GetSchema メソッド
  DAO.Field.Type プロパティ 
  ADOX.Column.Type プロパティ 
あたりを使った方が正確な情報を得られる気がします(未確認)。

編集 削除
魔界の仮面弁士  2011-01-11 10:43:55  No: 147287  IP: [192.*.*.*]

> あたりを使った方が正確な情報を得られる気がします(未確認)。
試してみました。やはりスキーマ経由の方が良さそうです。


Dim con As New OleDbConnection("Provider=Microsoft.JET.OLEDB.4.0;Data Source=C:\db1.mdb")
con.Open()
Dim cmd As OleDbCommand = con.CreateCommand()
cmd.CommandText = "CREATE TABLE TEST (COL1 AUTOINCREMENT(100, 1) PRIMARY KEY, COL2 TEXT(20), COL3 CHAR(20), COL4 MEMO, COL5 NUMERIC(5, 2), COL6 INTEGER )"
cmd.ExecuteNonQuery()
cmd.CommandText = "INSERT INTO TEST (COL2, COL3, COL4, COL5, COL6) VALUES ( 'aaa', 'bbb', 'ccc', 123.45, 12345 )"
cmd.ExecuteNonQuery()

Dim ds As New DataSet()
Dim da As New OleDbDataAdapter("SELECT * FROM TEST", con)
da.SelectCommand.Prepare()
da.Fill(ds, "TEST")
Dim tbl As DataTable = ds.Tables("TEST")

Dim reader As OleDbDataReader = da.SelectCommand.ExecuteReader()
Dim schema As DataTable = reader.GetSchemaTable()
reader.Close()

con.Close()

Console.Clear()

'既存の方式
Console.WriteLine("=== DataColumn 経由での取得 ===")
For Each col As DataColumn In tbl.Columns
    Console.WriteLine("No={0}", col.Ordinal)
    Console.WriteLine("Name={0}", col.ColumnName)
    Console.WriteLine("Type={0}", col.DataType.FullName)
    Console.WriteLine("MaxLength={0:#,0}", col.MaxLength)
    Console.WriteLine()
Next

'★本題★
Console.WriteLine("=== スキーマ 経由での取得 ===")
For Each row As DataRow In schema.Rows
    Console.WriteLine("No={0}", row("ColumnOrdinal"))
    Console.WriteLine("Name={0}", row("ColumnName"))
    Console.WriteLine("Type={0}", row("ProviderType"))
    Console.WriteLine("Size={0:#,0}", row("ColumnSize"))
    Console.WriteLine("Precision={0}", row("NumericPrecision"))
    Console.WriteLine("Scale={0}", row("NumericScale"))
    Console.WriteLine()
Next

MsgBox("完了", vbSystemModal)


なお、row("ProviderType") で得られる値については、
ADODB.DataTypeEnum 列挙体で示されています。
http://msdn.microsoft.com/en-us/library/ms675318.aspx

編集 削除
えどたつ  2011-01-11 13:29:06  No: 147288  IP: [192.*.*.*]

魔界の仮面弁士さんありがとうございました。

既存の方式という方ですと、
MaxLength=-1
となってしまいますので、スキーマ経由でやってみようと思います。

具体的なコードを書いていただいたので、すぐに試すことができました。
大変助かりました。
ありがとうございました。

編集 削除