Почему разница в конце скрипта PowerShell имеет значение? - PullRequest
1 голос
/ 26 апреля 2011

3-е редактирование:

Единственное различие между следующими двумя сценариями (помимо имени функции) заключается в том, что второй не возвращает результат посредством явного возврата. Но они ведут себя по-другому. Первый показывает две строки

abc
efg

в сетке, в то время как второй показывает пустых строк в сетке.

Скрипт 1:

ipmo WPK

$ConnectionString = $ConnectionString = "Server=localhost;Integrated Security=True"
$conn = new-object System.Data.SQLClient.SQLConnection
$conn.ConnectionString = $ConnectionString 
$conn.Open() 

function Invoke-sql1
{
    param( [string]$sql,
           [System.Data.SQLClient.SQLConnection]$connection
           )
    $cmd = new-object System.Data.SQLClient.SQLCommand($sql,$connection)
    $ds = New-Object system.Data.DataSet
    $da = New-Object System.Data.SQLClient.SQLDataAdapter($cmd)
    $da.fill($ds) | Out-Null
    return $ds.tables[0]
}

function Show-Bockmarks ($conn) {
        New-ListView -Name ListView -View {
           New-GridView -AllowsColumnReorder -Columns {
               New-GridViewColumn "title" 
           }
    } -show -On_Loaded {
            $ff_sql = @"
SELECT 'abc' title
UNION
SELECT 'efg' title
"@
            $TableView = $window | Get-ChildControl ListView
            $TableView.ItemsSource = @(Invoke-sql1 -sql $ff_sql -connection $conn)
             } 
}

Show-Bockmarks $conn

Сценарий 2:

ipmo WPK

$ConnectionString = $ConnectionString = "Server=localhost;Integrated Security=True"
$conn = new-object System.Data.SQLClient.SQLConnection
$conn.ConnectionString = $ConnectionString 
$conn.Open() 

function Invoke-sql2
{
    param( [string]$sql,
           [System.Data.SQLClient.SQLConnection]$connection
           )
    $cmd = new-object System.Data.SQLClient.SQLCommand($sql,$connection)
    $ds = New-Object system.Data.DataSet
    $da = New-Object System.Data.SQLClient.SQLDataAdapter($cmd)
    $da.fill($ds) | Out-Null
    $ds.tables[0]
}

function Show-Bockmarks ($conn) {
        New-ListView -Name ListView -View {
           New-GridView -AllowsColumnReorder -Columns {
               New-GridViewColumn "title" 
           }
    } -show -On_Loaded {
            $ff_sql = @"
SELECT 'abc' title
UNION
SELECT 'efg' title
"@
            $TableView = $window | Get-ChildControl ListView
            $TableView.ItemsSource = @(Invoke-sql2 -sql $ff_sql -connection $conn)
             } 
}

Show-Bockmarks $conn

Первый скрипт показывает 2 строки в сетке, а второй показывает пустые строки в сетке. Второй, похоже, ведет себя подобно этому

3-й скрипт, не использующий функцию:

ipmo WPK

$ConnectionString = $ConnectionString = "Server=localhost;Integrated Security=True"
$conn = new-object System.Data.SQLClient.SQLConnection
$conn.ConnectionString = $ConnectionString 
$conn.Open() 

            $ff_sql = @"
SELECT 'abc' title
UNION
SELECT 'efg' title
"@

function Show-Bockmarks ($conn) {
        New-ListView -Name ListView -View {
           New-GridView -AllowsColumnReorder -Columns {
               New-GridViewColumn "title" 
           }
    } -show -On_Loaded {
        $TableView = $window | Get-ChildControl ListView
        $cmd = new-object System.Data.SQLClient.SQLCommand($ff_sql,$conn)
        $ds = New-Object system.Data.DataSet
        $da = New-Object System.Data.SQLClient.SQLDataAdapter($cmd)
        $da.fill($ds) | Out-Null
        $TableView.ItemsSource = @($ds.tables[0].rows)
    } 
}

Show-Bockmarks $conn

Обратите внимание, здесь без использования функции я должен явно использовать $ ds.tables [0] .rows . В противном случае я получаю ошибку

Exception setting "ItemsSource": "Cannot convert the "Table" 
value of type "System.Data.DataTable" 
to type "System.Collections.IEnumerable"."

Функция PowerShell не будет возвращать объект может объяснить, почему эта функция похожа на функцию без возврата. Но как при возврате эти 2 строки отображаются в сетке?

Оригинальный пост:

Функции Invoke-sqlite и Invoke-sqlite1 практически одинаковы.

Единственное отличие состоит в том, что Invoke-sqlite использует явный возврат. Разница очень тонкая, когда я выполняю

$o1   =  Invoke-sqlite $sql $conn
$o2   =  Invoke-sqlite2 $sql $conn

Я не вижу никакой разницы. Но в полном контексте сценария, приведенного ниже, в Invoke-sqlite сетка заполнена данными, а в Invoke-sqlite сетка заполнена пустыми строками.

Кстати: цель сценария - поиск в копии базы данных истории Firefox place.sqlite для закладок с комбинациями от 1 до 3 ключевых слов. Вы должны изменить путь для строки dll 5 и путь для строки базы данных sqlite 8.

Если у вас проблемы с System.Data.SQLite.dll, см. this

ipmo WPK

if (! $sqlitedll)
{
    $sqlitedll = [System.Reflection.Assembly]::LoadFrom("C:\Program Files\System.Data.SQLite\bin\System.Data.SQLite.dll") 
}

$ConnectionString = "Data Source=C:\Var\sqlite_ff4\places.sqlite"

$conn = new-object System.Data.SQLite.SQLiteConnection 
$conn.ConnectionString = $ConnectionString 
$conn.Open() 

# $sql = "SELECT * from moz_bookmarks t1 where parent = 4 and t1.title = 'sqlite' or t1.title = 'sql'"

function Invoke-sqlite
{
    param( [string]$sql,
           [System.Data.SQLite.SQLiteConnection]$connection
           )
    $cmd = new-object System.Data.SQLite.SQLiteCommand($sql,$connection)
    $ds = New-Object system.Data.DataSet
    $da = New-Object System.Data.SQLite.SQLiteDataAdapter($cmd)
    $da.fill($ds) | Out-Null
    return $ds.tables[0]
}

function Invoke-sqlite2
{
    param( [string]$sql,
           [System.Data.SQLite.SQLiteConnection]$connection
           )
    $cmd = new-object System.Data.SQLite.SQLiteCommand($sql,$connection)
    $ds = New-Object system.Data.DataSet
    $da = New-Object System.Data.SQLite.SQLiteDataAdapter($cmd)
    $da.fill($ds) | Out-Null
    $ds.tables[0]
}

# $o1   =  Invoke-sqlite $sql $conn
# $o2   =  Invoke-sqlite2 $sql $conn


function Show-Bockmarks ($resource) {
    #New-StackPanel -Orientation vertical {
    New-Grid -Rows 2 -Columns 1 -width 1400 -hight 1000 {

        New-StackPanel -Orientation horizontal -column 0 -row 0 -Children {
             New-Label    '1. Keyword'
             New-TextBox  -Name tag1 -width 200
             New-Label    '2. Keyword'
             New-TextBox  -Name tag2 -width 200
             New-Label    '3. Keyword'
             New-TextBox  -Name tag3 -width 200
             New-Button -Name Search "search" -On_Click {
            $text1 = $window | Get-ChildControl Tag1
            $tag1 = $text1.Text
            $text2 = $window | Get-ChildControl Tag2
            $tag2 = $text2.Text
            $text3 = $window | Get-ChildControl Tag3
            $tag3 = $text3.Text
            if ( $tag2 -ne '') {
$clause2 = @"            
    join moz_bookmarks l2 on b.fk = l2.fk and b.id <> l2.id
    join moz_bookmarks t2 on l2.parent = t2.id and  t2.parent = 4 and upper(t2.title) = upper('$tag2')
"@                        
            } else { $clause2 = '' }        

            if ( $tag3 -ne '') {
$clause3 = @"            
    join moz_bookmarks l3 on b.fk = l3.fk and b.id <> l3.id
    join moz_bookmarks t3 on l3.parent = t3.id and  t3.parent = 4 and upper(t3.title) = upper('$tag3')
"@                        
            } else { $clause3 = '' }        

$ff_sql = @"
SELECT b.title, datetime (b.dateAdded / 1000000, 'unixepoch', 'localtime') dateAdded , p.url
    from moz_bookmarks b
    join moz_bookmarks l1 on b.fk = l1.fk and b.id <> l1.id
    join moz_bookmarks t1 on l1.parent = t1.id and  t1.parent = 4 and upper(t1.title) = upper('$tag1')
    join moz_places p  on b.fk = p.id $clause2 $clause3
where b.title is not null and b.type = 1
"@
#             $query = $window | Get-ChildControl query
#             $query.text = $ff_sql
            $conn = $resource.conn
            $window.Title = "$($conn.database) Database Browser"
            $TableView = $window | Get-ChildControl TableView
            $TableView.ItemsSource = Invoke-sqlite -sql $ff_sql -connection $conn
             } 
#             New-textbox -Name query 
             New-Button -Name Cancel "Close" -On_Click {$window.Close()} 
        }
        # -VerticalScrollBar $True 
        # New-ScrollViewer {
        New-ListView -Column 0 -Row 1 -Name TableView -View {
           New-GridView -AllowsColumnReorder -Columns {
               New-GridViewColumn "title" 
               New-GridViewColumn "dateAdded" 
               New-GridViewColumn "url" 
           }
        }   -On_SelectionChanged {
             start $this.selecteditem.url
        }
        #}

    } -asjob -Resource $resource
}

Show-Bockmarks -resource @{conn = $conn}

1 Ответ

0 голосов
/ 27 апреля 2011

Чтобы помочь, я написал то же самое в верхней части SQLClient, и, похоже, он работает нормально.

function func1
{
  param( [string]$sql,
         [System.Data.SQLClient.SQLConnection]$connection
     )


  $cmd = new-object System.Data.SQLClient.SQLCommand($sql,$conn)
  $ds = New-Object system.Data.DataSet
  $da = New-Object System.Data.SQLClient.SQLDataAdapter($cmd)
  $da.fill($ds) | Out-Null

  $ds.Tables[0]
}

function func2
{
  param( [string]$sql,
       [System.Data.SQLClient.SQLConnection]$connection
     )


  $cmd = new-object System.Data.SQLClient.SQLCommand($sql,$conn)
  $ds = New-Object system.Data.DataSet
  $da = New-Object System.Data.SQLClient.SQLDataAdapter($cmd)
  $da.fill($ds) | Out-Null

  return $ds.Tables[0]
}

Clear-Host

$sqldll = [reflection.assembly]::loadwithpartialname("System.Data.SqlClient")
$connectionString="Data Source=JPBHPP2\SQLEXPRESS;Initial Catalog=Ardeche-Earth;Integrated Security=True"

$conn = new-object System.Data.SQLClient.SQLConnection 
$sql = "SELECT * FROM communes WHERE COM_NCC LIKE 'AURI%'"
$conn.ConnectionString = $ConnectionString 
$conn.Open() 

$a = func1 -sql $sql -connection $conn
$b = func2 -sql $sql -connection $conn

Write-Host "`$a : $($a.count)"
Write-Host "`$b : $($b.count)"

$conn.Close() 

$ a и $ b содержат один и тот же массив System.Data.DataRow в конце

...