programing

DataSet/DataTable을 반환하는 PowerShell 함수의 이상한 동작

testmans 2023. 10. 12. 22:15
반응형

DataSet/DataTable을 반환하는 PowerShell 함수의 이상한 동작

정말 미칠 것 같아요.다음 기능을 포함하는 여러 스크립트에서 출처한 라이브러리가 있습니다.

function lib_open_dataset([string] $sql) {
    $ds = new-object "System.Data.DataSet"
    $da = new-object "System.Data.SqlClient.SqlDataAdapter" ($sql, $_conn_string)

    $record_count = $da.Fill($ds)

    return $ds
}

이것은 거의 모든 곳에서 사용되며 보통 이 작업을 수행해야 하는 것을 제외하고는 잘 작동합니다.

$ds = lib_open_dataset($some_sql)
$table = $ds.Tables[0]
foreach ($row in $table.Rows) {
    # etc
}

그래서 첫 번째 테이블을 다시 참조하는 추가 단계를 피하기 위해 간단한 래퍼 기능을 새로 만들었습니다.

function lib_open_table([string] $sql) {
    $ds = lib_open_dataset $sql
    return $ds.Tables[0]
}

문제는 여기서 반환되는 것이 테이블 자체가 아니라 어떤 이유에서인지 테이블의 행 모음이라는 것입니다.이것이 원인입니다.foreachnull array에 인덱스를 입력할 수 없습니다. 예외와 함께 실패하려면 위와 같이 행 루프를 씁니다.시행착오를 거듭한 끝에 다음과 같은 결과를 얻었습니다.

foreach ($row in $table) {
    # etc
}

사이의 차이를 기록합니다.$table.Rows그리고 그냥$table에서foreach진술.이거 됩니다.왜냐면$table실제로 행 집합을 가리킵니다.만약 그 명세서가

return $ds.Tables[0]

맞는 것 같습니다. 함수가 테이블 자체가 아닌 테이블 개체의 하위 컬렉션을 반환하는 이유는 무엇입니까?

파워셸 기능이 작동하는 방식에 뭔가 문제가 있는 것 같은데, 뭐가 원인인지 모르겠어요.

쉼표 연산자를 사용하여 행 집합을 배열로 래핑할 수 있으므로 배열을 펼쳤을 때 원래 행 집합으로 마무리할 수 있습니다(예:

function lib_open_table([string] $sql) {
    $ds = lib_open_dataset $sql    
    return ,$ds.Tables[0]
}

근본적으로 PowerShell이 어레이/컬렉션을 실행하지 못하도록 방지할 수는 없습니다.다른 단일 요소 배열 내에서 배열/집합을 래핑하여 이 동작을 해결하는 것이 최선의 방법입니다.

PowerShell: DataTable을 내부적으로 특별하게 활용합니다.일반적으로 실행 해제를 트리거하는 ICollection, IList 또는 IEnumberable과 같은 일반적인 의심스러운 인터페이스는 구현하지 않습니다.다음을 통해 이에 대해 자세히 설명할 수 있습니다.

PS> $dt = new-object data.datatable
PS> $dt -is [collections.ienumerable]
False

아직:

PS> $e = [management.automation.languageprimitives]::GetEnumerator($dt)
PS> $e.gettype()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
False    False    RBTreeEnumerator                         System.ValueType

-오이신

a) 반환된 개체에 쉼표를 붙여서 어댑터를 채울 때 반드시 결과를 (일회용) 변수에 할당하거나 Out-Null을 수행해야 하는 2가지 사항

Out-Null을 수행하지 않았고 미리 지정된 쉼표가 있어도 계속 컬렉션을 반환했습니다(항목 0 = 쿼리의 행 수, 항목 1 = 데이터 테이블) Out-null 매개 변수를 선택할 때까지 약간 미쳤습니다.

매우 이상한 IMHO, 제가 특별히 데이터 테이블을 돌려달라고 요청하고 있는데도 계속 컬렉션을 돌려받아서, 심지어 ""앞에 있는"것을 가지고도 말입니다.

function  Oracleconnection
{
  process
  {
  trap
    {
      Write-Host "error occured on oracle connection"
      Write-Host $_
      continue
    }
    [System.Reflection.Assembly]::LoadWithPartialName(“System.Data.OracleClient”) | out-null
    $connection = new-object system.data.oracleclient.oracleconnection( `
    "Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=myhost.host)(PORT=1800)) `
    (CONNECT_DATA=(SERVICE_NAME=myservicename)));User Id=myid;Password=mypassword;");

    $query = "SELECT country, asset FROM table "
    $set = new-object system.data.dataset
    $adapter = new-object system.data.oracleclient.oracledataadapter ($query, $connection)
    $adapter.Fill($set) | Out-Null
    $table = new-object system.data.datatable
    $table = $set.Tables[0]
    return ,$table
  }
}

(Keith의 답변에서 나온 개념들!)

언급URL : https://stackoverflow.com/questions/1918190/strange-behavior-in-powershell-function-returning-dataset-datatable

반응형