2017-08-13 73 views
1

我想写一个Powershell脚本来将数据写入SQLite数据库并从中读取数据。我正在使用PSSQLite模块来执行此操作。该脚本在一台服务器上工作,但不在另一台服务器上。这两台机器都是Windows 2012 R2。使用Powershell和PSSqlite进行SQLite访问 - SELECT查询失败

这两款机器是这样的:

PS C:\> $PSVersionTable 

Name       Value 
----       ----- 
PSVersion      5.0.10586.117 
PSCompatibleVersions   {1.0, 2.0, 3.0, 4.0...} 
BuildVersion     10.0.10586.117 
CLRVersion      4.0.30319.42000 
WSManStackVersion    3.0 
PSRemotingProtocolVersion  2.3 
SerializationVersion   1.1.0.1 


PS C:\> Import-Module PSSQLite 
PS C:\> Get-Module PSSQLite 

ModuleType Version Name        ExportedCommands 
---------- ------- ----        ---------------- 
Script  1.0.3  PSSQLite       {Invoke-SQLiteBulkCopy, Invoke-SqliteQuery, New-SQLiteConn... 

PS C:\> 

我有一个简短的PowerShell脚本来创建一个SQLite数据库,在其中创建一个表中,填写表,然后从表中读取。该脚本是这样的:

Import-Module PSSQLite 
$secretsDatabase = ".\secrets.db" 

if (Test-Path $secretsDatabase) { 
    Write-Host "$secretsDatabase already exists" 
} else { 
    $create_query = "create table secrets (tid string, password string, username string)" 
    $cq_result = Invoke-SqliteQuery -DataSource $secretsDatabase -Query $create_query 

    $add_secrets_query = "insert into secrets (tid, password, username) values ('xx1', 'somepassword', '[email protected]')" 
    $as_result = Invoke-SqliteQuery -DataSource $secretsDatabase -Query $add_secrets_query 
} 

$secretsQuery = "select tid, password, username from secrets limit 1" 

$result = Invoke-SqliteQuery -DataSource $secretsDatabase -Query $secretsQuery 
Write-Host $result 

当我在一台服务器上运行此PowerShell脚本,输出看起来是这样的:

PS C:\> C:\sqlite_test.ps1 
.\secrets.db already exists 
@{tid=xx1; password=somepassword; [email protected]} 

PS C:\> 

这是预期的输出。

当我运行在其他服务器上相同的脚本,输出看起来是这样的:

PS C:\> C:\sqlite_test.ps1 
.\secrets.db already exists 
Unable to find type [DBNullScrubber]. 
At C:\Program Files\WindowsPowerShell\Modules\PSSQLite\1.0.3\Invoke-SqliteQuery.ps1:518 char:25 
+       [DBNullScrubber]::DataRowToPSObject($row) 
+       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
    + CategoryInfo   : InvalidOperation: (DBNullScrubber:TypeName) [], RuntimeException 
    + FullyQualifiedErrorId : TypeNotFound 


PS C:\> 

在两个系统中,SQL查询创建一个表并插入一行的作品。这是通过使用在两台机器上的命令行实用程序和得到这个结果证明:

C:\> sqlite3 secrets.db 
SQLite version 3.19.3 2017-06-08 14:26:16 
Enter ".help" for usage hints. 
sqlite> .dump 
PRAGMA foreign_keys=OFF; 
BEGIN TRANSACTION; 
CREATE TABLE secrets (tid string, password string, username string); 
INSERT INTO secrets VALUES('xx1','somepassword','[email protected]'); 
COMMIT; 
sqlite> 

但是一台机器上的SELECT查询失败,因为“[DBNullScrubber]”的错误。如何在一台机器上纠正这个问题?

------更新:2017年8月13日更多的分析-----------------

我做了一些代码在GitHub库这个洞穴探险模块,插入文件

Invoke-SqliteQuery.ps1

我走进我的PowerShell中的坏服务器上跑从该文件中的代码片段:

$cSharp = @' 
       using System; 
       using System.Data; 
       using System.Management.Automation; 

       public class DBNullScrubber 
       { 
        public static PSObject DataRowToPSObject(DataRow row) 
        { 
         PSObject psObject = new PSObject(); 

         if (row != null && (row.RowState & DataRowState.Detached) != DataRowState.Detached) 
         { 
          foreach (DataColumn column in row.Table.Columns) 
          { 
           Object value = null; 
           if (!row.IsNull(column)) 
           { 
            value = row[column]; 
           } 

           psObject.Properties.Add(new PSNoteProperty(column.ColumnName, value)); 
          } 
         } 

         return psObject; 
        } 
       } 
'@ 

这段代码定义DBNullScrubber类。在那之后,我去了我的命令行的不良服务器上跑:

PS C:\> Add-Type -TypeDefinition $cSharp -ReferencedAssemblies 'System.Data','System.Xml' 
Add-Type : (0) : Warning as Error: Invalid search path 'D:\Program Files\IBM\SQLLIB\LIB' specified in 'LIB environment variable' -- 'The system cannot find 
the path specified. ' 
(1) :     using System; 
At line:1 char:2 
+ Add-Type -TypeDefinition $cSharp -ReferencedAssemblies 'System.Data' ... 
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
    + CategoryInfo   : InvalidData: (error CS1668: W...th specified. ':CompilerError) [Add-Type], Exception 
    + FullyQualifiedErrorId : SOURCE_CODE_ERROR,Microsoft.PowerShell.Commands.AddTypeCommand 

Add-Type : Cannot add type. Compilation errors occurred. 
At line:1 char:2 
+ Add-Type -TypeDefinition $cSharp -ReferencedAssemblies 'System.Data' ... 
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
    + CategoryInfo   : InvalidData: (:) [Add-Type], InvalidOperationException 
    + FullyQualifiedErrorId : COMPILER_ERRORS,Microsoft.PowerShell.Commands.AddTypeCommand 


PS C:> 

我跑这个良好的服务器上,并没有任何错误。

在这一点上,我不知道该怎么做。我怎样才能解决这个问题?

-----------------更新2017年8月13日 - 12:11 ----------------

我打印出$ env:Lib。好机器上没有定义。在坏机器上它说:

PS C:\> $env:Lib 
;D:\Program Files\IBM\SQLLIB\LIB 
PS C:\> 
+1

显示'$ env:LIB'。 – PetSerAl

回答

0

运行以下操作删除Lib环境变量。

Remove-Item $env:Lib 

更好的是,保存旧值,运行脚本,然后恢复旧值。

Import-Module PSSQLite 
$secretsDatabase = ".\secrets.db" 

$envlib = $env:Lib 
Remove-Item env:Lib 

if (Test-Path $secretsDatabase) { 
    Write-Host "$secretsDatabase already exists" 
} else { 
    $create_query = "create table secrets (tid string, password string, username string)" 
    $cq_result = Invoke-SqliteQuery -DataSource $secretsDatabase -Query $create_query 

    $add_secrets_query = "insert into secrets (tid, password, username) values ('xx1', 'somepassword', '[email protected]')" 
    $as_result = Invoke-SqliteQuery -DataSource $secretsDatabase -Query $add_secrets_query 
} 

$secretsQuery = "select tid, password, username from secrets limit 1" 

$result = Invoke-SqliteQuery -DataSource $secretsDatabase -Query $secretsQuery 
Write-Host $result 

$env:Lib = $envlib