1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

今日のトリビア PowershellでSQLを使用してMicrosoft Accessのテーブルを作成するときは WITH COMP属性は特定の場合以外エラーになる

Last updated at Posted at 2022-11-28

環境

  • Powershell_ise 5.1
  • Access 32bitくらい
  • Windows10 くらい

再現手順

Powershell_iseでこんなコードを実行する。
定数の設定、既存ファイルチェックとかは省略している。

 $acApp = New-Object -ComObject Access.Application;
 $acApp.NewCurrentDataBase((Join-Path $sFolder $ac2007),$acNewDatabaseFormatAccess12);
 $acApp.CloseCurrentDataBase(); # いったん閉じる
 $dao = New-Object -ComObject DataEngine.Dao.120
 $ModeNum=2
 IF($ModeNum -eq 1){
 $cDB=$dao.OpenDatabase((Join-Path $sFolder $ac2007))
 $sCNSQL=  "CREATE TABLE T_Masterファイルリスト(ID Counter Primary Key, 作成DT DATE,"  `                                     +  "接続DT DATE, 更新DT DATE," `
          +  "[ディレクトリ] MEMO WITH COMP, フルネーム MEMO WITH COMP," `
          +  "ファイルN Text(255), ベースN Text(255), 拡張子 Text(10));"
$cDB.execute($sCNSQL) ; $cDB.TableDefs.Refresh() ;
$cDB.Close()
}Else{
$aCN2= New-Object -ComObject Adodb.Connection
$Db= Join-Path $sFolder $ac2007
$aCN2.Open("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=$sFolder")
$sCNSQL=  "CREATE TABLE T_Masterファイルリスト(ID Counter Primary Key, 作成DT DATE,"  `                                     +  "接続DT DATE, 更新DT DATE," `
         +  "[ディレクトリ] MEMO WITH COMP, フルネーム MEMO WITH COMP," `
         +  "ファイルN Text(255), ベースN Text(255), 拡張子 Text(10));"
$aCN2.Execute($sCNSQL)
$aCN2.Close()
$aCN2=$null
}

問題

この前段でUTF-8で作成されたCSVを読み込みます。
そのCSVはサーバーにあるファイルのリストです。
サーバーにある名前は長く色々です。
このため、MEMO型を使います。
$ModeNum=1のときはDAOで、それ以外はADODBで接続してテーブルを作ります。
このとき、両方とも問題なくテーブルが作られるでしょうか

答え

Daoは失敗する。
ADODBは成功する。

CREATE TABLE ステートメント (Microsoft Access SQL)
[アーティクル]
2022/08/31
適用先: Access 2013、Office 2013
新しいテーブルを作成します。

注意
Microsoft Access データベース エンジンは、Microsoft Access データベース エンジン以外のデータベースでは CREATE TABLE 句や DDL (データ定義言語) ステートメントを使用できません。Microsoft Access データベース エンジン以外のデータベースでは代わりに DAO の Create 系メソッドを使用してください。

このような見出しを見ると、DAOを使ったほうが良いようだが、実は古くから知られている。
そしてやっぱり魔界の仮面弁士氏である。

オートナンバー属性に設定するには?

はづき  2003-04-02 11:51:56 No: 77518

連投稿申し訳ありません
先の方法でフィールドの追加ができました
ご教授ありがとうございました

オートナンバー型に設定ができません
長整数などならDBLONG等でできるようですが
オートナンバーに設定することができません

フィールド作成時もしくは作成後にオートナンバーに設定する方法
お願いします・・・


魔界の仮面弁士  2003-04-02 19:10:28 No: 77519
夜遅くまでご苦労様です。
ADOやDAOのオブジェクトモデルを使っても追加できるのですが、
今回はSQL文で指定する方法を回答しますね。
(オブジェクトで追加する方法が知りたい場合は、再質問してください)
(中略)
[新規表にオートナンバー列を作成]

先と同様、"COUNTER" もしくは "AUTOINCREMENT" で指定します。
例えば、以下のようなSQL文が利用できます。

CREATE TABLE 従業員 (
   社員番号 AUTOINCREMENT CONSTRAINT PK_社員番号 PRIMARY KEY,
   社員姓 TEXT(50) WITH COMP NOT NULL,
   社員名 TEXT(50) WITH COMPRESSION NOT NULL,
   電話番号 TEXT(10),
   Email TEXT(50),
   住所 TEXT(40) DEFAULT 不明)

これは、以下のような[従業員]というテーブルを作成するための物です。

  社員番号: オートナンバー(初期値=1、増分値=1)
  社員姓  : テキスト型(50文字、Unicode圧縮あり) [値要求あり]
  社員名  : 文字列型(50文字、Unicode圧縮あり) [値要求あり]
  電話番号: 文字列型(10文字、Unicode圧縮なし) [値要求なし]
  Email   : 文字列型(50文字、Unicode圧縮なし) [値要求なし]
  住所    : 文字列型(50文字、Unicode圧縮なし) [値要求なし、初期値=不明]

また、CONSTRAINT指定により、このテーブルには[社員番号]列に対して
"PK_社員番号" という名前の主キーが設けられています。

# なお上記には Microsoft.ACE.OLEDB.12.0Jet 4.0の ANSI-92モードでしか利用できないキーワードが
# いくつか含まれていますので(WITH COMPやDEFAULT等)、このままですと、
# 「ADO + "Microsoft.ACE.OLEDB.12.0""Microsoft.Jet.OLEDB.4.0"」以外から実行する事はできません。
DAOから実行したい場合には、WITH COMP等のキーワードを削って、
# ANSI-89モードのSQL構文にしてから試してみてください。

2022年現在に読み変えると

このJETは今ではあまり使われないのでMicrosoft ACE 12.0に置き換えて読むと、実は今でも通じるということになる。

クエリではたしかにWITH COMPは使えない

image.png

image.png

Create Table T_Master(fld01 MEMO WITH COMP);

VBAでは

DAO

CurrentDBはDao.Databeseなので、DAOになる。

Sub test()
Dim cDB As DAO.Database
Set cDB = CurrentDb
Dim Q As QueryDef
cDB.Execute ("Create Table T_Master(fld01 MEMO WITH COMP);")
End Sub

これは構文エラーになる

Sub test2()
Dim cDB As DAO.Database
Set cDB = CurrentDb
Dim Q As QueryDef
cDB.Execute ("Create Table T_Master(fld01 MEMO);")
Application.RefreshDatabaseWindow
End Sub

成功する。やはりDAOではWITHが使えない。

Sub test3()
Dim cDB As DAO.Database
Dim CN As Object: Set CN = CreateObject("ADODB.Connection")
Set cDB = CurrentDb
Dim Q As QueryDef
Set CN = CurrentProject.AccessConnection
CN.Execute "Create Table T_Master(fld01 MEMO WITH COMP);"
Application.RefreshDatabaseWindow
End Sub

ADOは成功する。VBAでもWITH COMPはADOを使ったときだけである。

それではDAOは役立たないのか

このWITH COMP属性はUTF-8のCSVを読み込ませるときデータ型が違うとしてエラーになる場合がある。
これを解決するにはUTF-8ではなくUNICODE(とMSが言っているUTF-16)でCSVを作るか、WITH COMPを使わないでDAOで作成するかである。
UTF-8のほうが汎用性が高く、DAOを使うほうが基本的に早いため、WITH COMPを使わないDAOにも活躍の余地がある。
さらにDAOは接続文字列を使わないため、コードも短く、簡潔である。さらにアクションクエリでもWITH COMPは使えない。ご覧のようにWITHでエラーになる。クエリとVBAで同じSQLが使える。つまりSQL文を共用できる。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?