SQLite access using Powershell and PSSqlite - SELECT query fails

折月煮酒 提交于 2020-01-15 09:34:44

问题


I am trying to write a Powershell script to write data to a SQLite database and to read from it. I'm using the PSSQLite module to do this. The script works on one server, but not on the other. Both machines are Windows 2012 R2.

Both machines look like this:

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:\>

I have a short Powershell script to create a SQLite database, create a table within it, write to the table, and then read from the table. The script looks like this:

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

When I run this Powershell script on one server, the output looks like this:

PS C:\> C:\sqlite_test.ps1
.\secrets.db  already exists
@{tid=xx1; password=somepassword; username=bob@example.com}

PS C:\>

This is the expected output.

When I run the same script on the other server, the output looks like this:

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:\> 

On both systems, the SQL queries to create a table and to insert a row works. This is evidenced by using the command line utility on both machines and getting this result:

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>

However the SELECT query on one machine fails because of the "[DBNullScrubber]" error. How can I correct this problem on the one machine?

------ UPDATE: August 13, 2017 more analysis -----------------

I did some code spelunking at the GitHub repo for this module, into the file

Invoke-SqliteQuery.ps1

I went into my Powershell on the bad server and ran this code snippet from that file:

$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;
                    }
                }
'@

This snippet defines the DBNullScrubber class. After that, I went to my command line on the bad server and ran:

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:> 

I ran this on the good server and there were no errors.

At this point I don't know what to do. How can I fix this?

----------------- Update Aug 13, 2017 - 12:11 ----------------

I printed out $env:Lib. There was nothing defined on the good machine. On the bad machine it said:

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

回答1:


Run the following to delete the Lib environment variable.

Remove-Item $env:Lib

Better yet, save the old value, run the script, and then restore the old value.

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


来源:https://stackoverflow.com/questions/45656894/sqlite-access-using-powershell-and-pssqlite-select-query-fails

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!