使用Powershell和PSSqlite进行SQLite访问 - SELECT查询失败

时间:2017-08-13 03:50:46

标签: windows powershell sqlite

我正在尝试编写一个Powershell脚本来将数据写入SQLite数据库并从中读取数据。我使用PSSQLite模块执行此操作。该脚本在一台服务器上运行,但在另一台服务器上运行。这两台机器都是Windows 2012 R2。

两台机器都是这样的:

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', 'bob@example.com')"
   $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; username=bob@example.com}

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','bob@example.com');
COMMIT;
sqlite>

然而,由于" [DBNullScrubber]"在一台机器上的SELECT查询失败。错误。如何在一台机器上纠正这个问题?

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

我在GitHub repo上为这个模块做了一些代码,进入文件

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 个答案:

答案 0 :(得分:1)

运行以下命令以删除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', 'bob@example.com')"
   $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