的Windows XP專業版 的ActiveState Perl的5.14.4 M $ Access 2010中從Access 2010 ACCDB格式分貝
訪問MSysObjects我在其中包含存儲查詢的數量 ACCDB格式的Access數據庫。我想用Perl將它們提取到平面文件。
查詢名稱出現在[MSysObjects]。[Name]中,而查詢 本身似乎以某種方式存儲在MSysQueries中。
但我的問題是在上游 - 我無法讀取這些表中的任何一個。 我已經確認,當我直接打開數據庫的用戶名是「管理員」。
谷歌搜索變成了http://t1134.codeinpro.us/q/5080f5c04f1eba38a4d1547b, 這也解釋了「管理」沒有SELECT權限MSysObjects所以我需要 執行DDL語句GRANT SELECT ON MSysObjects管理員
更多谷歌搜索輪番上漲http://www.connectionstrings.com/access-2010,其中說: 啓用GRANT等特定管理語句我需要添加 Uid = Admin; PWD =; ExtendedAnsiSQL = 1; 我的連接字符串
而且同一頁面有一個Blurb的具體狀態,其中工作組文件是 位於 SystemDB = C:在連接字符串中\ mydatabase.mdw 。 更多相關內容。
所以我有這個
#! /home/gnu/bin/perl
#
package main;
use strict;
use autouse 'Data::Dumper' => qw(Dumper);
use DBI;
use DBD::ODBC; # works for both access and sql server
use Win32::ODBC;
use OLE;
use Win32::OLE;
# prototypes
sub _setUpDatabaseHandle_Access_Local_EnableAdminStatements($);
sub setPermissionsOnTables($);
sub readTableMSysObjects($);
#globals
my $debug = 1;
my $targetDbFile = undef;
my $dbh_C = undef;
print "version of DBD::ODBC is ".$DBD::ODBC::VERSION."\n";
print "version of Win32::ODBC is ".$Win32::ODBC::VERSION."\n";
print "version of Win32::OLE is ".$Win32::OLE::VERSION."\n";
$targetDbFile = "C:/putyer/msaccessdb/here.accdb";
$dbh_C = _setUpDatabaseHandle_Access_Local_EnableAdminStatements($targetDbFile);
setPermissionsOnTables($dbh_C);
readTableMSysObjects($dbh_C);
$dbh_C->disconnect() if(defined($dbh_C));
exit(0);
#-------------------------------
# when you use perl to open an .accdb Access database the Uid is always Admin
# But user Admin doesn't have SELECT permission on MSysObjects by default you must first
# grant the permission on the object for the user
# to enable certain admin commands like CREATE USER, GRANT, REVOKE, DEFAULTS when using CREATE TABLEs
sub _setUpDatabaseHandle_Access_Local_EnableAdminStatements($)
{
my ($dbFile) = @_;
my $errorHit = 0;
my $conn_str = "DBI:ODBC:DRIVER={Microsoft Access Driver (*.mdb, *.accdb)};dbq=".$dbFile;
$conn_str .= "; Uid=Admin; Pwd=; ExtendedAnsiSQL=1";
my $dbh = DBI->connect($conn_str);
if(!defined($dbh)) {
print "db connection failed - ".$DBI::errstr."\n";
$errorHit = 1;
}
print "connection _setUpDatabaseHandle_Access_Local_EnableAdminStatements failed\n" if($errorHit);
return $dbh;
}
#-------------------------------
sub setPermissionsOnTables($)
{
my ($dbh) = @_;
print "entering setPermissionsOnTables\n" if $debug;
my $errorHit = 0;
my $q = undef;
my $sth = undef;
unless($errorHit) {
$q = "GRANT SELECT ON MSysObjects TO Admin";
$sth = $dbh->prepare($q);
if(!defined($sth)) {
print "sth failed to define - ".$DBI::errstr."\n";
$errorHit = 1;
} else {
$sth->execute(); # <=== FAILS HERE
if(my $errorMsg = $dbh->errstr) {
print "select statement failed - ".$errorMsg."\n";
$errorHit = 1;
}
}
}
unless($errorHit) {
$q = "GRANT SELECT ON MSysQueries TO Admin";
$sth = $dbh->prepare($q);
if(!defined($sth)) {
print "sth failed to define - ".$DBI::errstr."\n";
$errorHit = 1;
} else {
$sth->execute();
if(my $errorMsg = $dbh->errstr) {
print "select statement failed - ".$errorMsg."\n";
$errorHit = 1;
}
}
}
print "exiting setPermissionsOnTables with errorHit=".$errorHit."\n" if $debug;
return $errorHit;
}
#-------------------------------
sub readTableMSysObjects($)
{
my ($dbh) = @_;
print "entering readTableMSysObjects\n" if $debug;
my $errorHit = 0;
my $q = undef;
my $sth = undef;
unless($errorHit) {
$q = "SELECT * FROM MSysObjects"; # remember that db nulls come over as perl undefs
$sth = $dbh->prepare($q);
if(!defined($sth)) {
print "sth failed to define - ".$DBI::errstr."\n";
$errorHit = 1;
} else {
$sth->execute();
if(my $errorMsg = $dbh->errstr) {
print "select statement failed - ".$errorMsg."\n";
$errorHit = 1;
} else {
if($sth->rows == 0) {
print "select statement returned 0 rows\n";
$errorHit = 1;
} else {
my $row_hashref = undef;
while($row_hashref = $sth->fetchrow_hashref()) {
print Dumper($row_hashref);
}
}
}
$sth->finish();
}
}
print "exiting readTableMSysObjects\n" if $debug;
return $errorHit;
}
試圖與臭名昭著 執行第一GRANT無法打開Microsoft Access數據庫引擎工作組信息文件 消息時失敗。
所以看來我也需要這個文件,我似乎無法在我的盒子上找到這個文件。 或者可以/我應該使用不同的連接?像其中之一?
#-------------------------------
sub _setUpDatabaseHandle_Access_Local_ADO_ACE($)
{
my ($dbFile) = @_;
my $errorHit = 0;
my $conn_str = "DBI:ADO:Provider=Microsoft.ACE.OLEDB.12.0;Data Source=".$dbFile;
$conn_str .= "; Persist Security Info=False";
# print $conn_str."\n";
my $dbh = DBI->connect($conn_str);
if(!defined($dbh)) {
_pushErrorMsg("db connection failed - ".$DBI::errstr);
$errorHit = 1;
}
print "connection _setUpDatabaseHandle_Access_Local_ACE failed\n" if($errorHit);
return $dbh;
}
#-------------------------------
sub _setUpDatabaseHandle_Access_Local_ADO($)
{
my ($dbFile) = @_;
my $errorHit = 0;
my $conn_str = "DBI:ADO:File Name=".$dbFile;
my $username = undef;
my $password = undef;
my $dbh = DBI->connect($conn_str, $username, $password);
if(!defined($dbh)) {
_pushErrorMsg("db connection failed - ".$DBI::errstr);
$errorHit = 1;
}
print "connection _setUpDatabaseHandle_Access_Local_ADO failed\n" if($errorHit);
return $dbh;
}
任何指針/提示/建設性的批評,尤其是例子都歡迎。
TIA,
還是學習史蒂夫
感謝您的回覆和示例!我會在第二天左右嘗試一下。 – user1201168