我正在使用System.Data.SQLite
SQLite的ADO.NET提供程序和以下Powershell代码对Sqlite3数据库执行查询(和非查询):
Function Invoke-SQLite ($DBFile,$Query) {
try {
Add-Type -Path ".\System.Data.SQLite.dll"
}
catch {
write-warning "Unable to load System.Data.SQLite.dll"
return
}
if (!$DBFile) {
throw "DB Not Found" R
Sleep 5
Exit
}
$conn = New-Object System.Data.SQLite.SQLiteConnection
$conn.ConnectionString="Data Source={0}" -f $DBFile
$conn.Open()
$cmd = $Conn.CreateCommand()
$cmd.CommandText = $Query
#$cmd.CommandTimeout = 10
$ds = New-Object system.Data.DataSet
$da = New-Object System.Data.SQLite.SQLiteDataAdapter($cmd)
[void]$da.fill($ds)
$cmd.Dispose()
$conn.Close()
write-host ("{0} Row(s) returned " -f ($ds.Tables[0].Rows|Measure-Object|Select -ExpandProperty Count))
return $ds.Tables[0]
}
问题是:虽然很容易知道在查询操作中选择了多少行,但是如果该操作是INSERT,DELETE或UPDATE(非查询),则情况并非如此
我知道我可以使用ExecuteNonQuery方法,但是我需要一个通用包装器,该包装器在不影响查询执行的情况下返回受影响的行数(例如,如Invoke-SQLCmd所做的那样)
有可能吗?
谢谢!
答案 0 :(得分:1)
答案前的一些评论:
$Query
中的语句类型之间进行区分的事实告诉我,您很可能只是盲目地传递语句,因此它可以包含语句的任何组合。仅获取一个值(无论是来自查询还是DML)似乎太局限了。$ds.Tables[0].Rows
必须为$ds.Tables[0].Rows.Count
。有关此特定解决方案的说明:
changes()
或total_changes()
中的一个。可以使用SQL:SELECT total_changes();
来检索它们。我建议在命令之前和之后获取total_changes()
,然后减去差值。这样一来,一条命令执行的多条语句就会发生变化。代码:
$conn = New-Object System.Data.SQLite.SQLiteConnection
try {
$conn.ConnectionString="Data Source={0}" -f $DBFile
$conn.Open()
$cmdCount = $Conn.CreateCommand()
$cmd = $Conn.CreateCommand()
try {
$cmdCount.CommandText = "SELECT total_changes();"
$beforeChanges = $cmdcount.ExecuteScalar()
$cmd.CommandText = $Query
$ds = New-Object System.Data.DataSet
$da = New-Object System.Data.SQLite.SQLiteDataAdapter($cmd)
$rows = 0
try {
[void]$da.fill($ds)
foreach ($tbl in $ds.Tables) {
$rows += $tbl.Rows.Count;
}
} catch {}
$afterChanges = $cmdcount.ExecuteScalar()
$DMLchanges = $afterChanges - $beforeChanges
$totalRowAndChanges = $rows + $DMLchanges
# $ds.Tables[0] may or may not be valid here.
# If query returned no data, no tables will exist.
} finally {
$cmdCount.Dispose()
$cmd.Dispose()
}
} finally {
$conn.Dispose()
}
或者,您可以消除DataAdapter:
$cmd.CommandText = $Query
$rdr = $cmd.ExecuteReader()
$rows = 0
do {
while ($rdr.Read()) {
$rows++
}
} while ($rdr.NextResult())
$rdr.Close();