Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Скриптовые языки администрирования Windows (http://forum.oszone.net/forumdisplay.php?f=102)
-   -   [решено] Преобразовать данные в DataTable (http://forum.oszone.net/showthread.php?t=350866)

Griboed0ff 15-03-2022 14:59 2981711

Преобразовать данные в DataTable
 
Доброго времени суток! Делаю запросы в базу через консольную утилиту sqlcl и пытаюсь привести ответ в нужную форму. А именно, в ответ от утилиты получаю System.Array с объектами. К объектам можно обратиться по индексу, но проблема в том, что PowerShell распознает разбивку на объекты неправильно. В ответе есть значение таблицы, которое содержит много строк и PowerShell каждую строку помечает как отдельный объект. В ответе два столбца и строки.
Примеры получаемых данных
Первая строка в ответах всегда пустая.
Пример вывода csv, System.Array, count 8:
Код:

"COUNT_ERROR","BODY_ERROR"
10412,"ERROR:РњTC:StatusLastOperation=RequestError Подробная ошибка=' ERROR: StatusLastOperation=ErrorReadingStreamException  Exception РїСЂРё чтении ответа сервера РњРўРЎ. Exception=System.Net.WebException: The remote serve
r returned an error: (400) Bad Request.
  at System.Net.HttpWebRequest.GetResponse()
  at SecureHttp.SecureHttpRequest.PostHttpData(String url, String postData, X509Certificate2 certificate) in y:\HttpRequest.cs:line 718'"
25,"ERROR:РњTC:StatusLastOperation=RequestError Подробная ошибка=' ERROR: StatusLastOperation=ErrorReadingStreamException  Exception РїСЂРё чтении ответа сервера РњРўРЎ. Exception=System.Net.WebException: The remote server r
eturned an error: (500) Internal Server Error.
  at System.Net.HttpWebRequest.GetResponse()
  at SecureHttp.SecureHttpRequest.PostHttpData(String url, String postData, X509Certificate2 certificate) in y:\HttpRequest.cs:line 718'"

Пример вывода xml, System.Array, count 16:
Код:


<?xml version='1.0'  encoding='UTF-8' ?>
<RESULTS>
        <ROW>
                <COLUMN NAME="COUNT_ERROR"><![CDATA[10513]]></COLUMN>
                <COLUMN NAME="BODY_ERROR"><![CDATA[ERROR:РњTC:StatusLastOperation=RequestError Подробная ошибка=' ERROR: StatusLastOperation=ErrorReadingStreamException  Exception РїСЂРё чтении ответа сервера РњРўРЎ. Exception=System.Net.
WebException: The remote server returned an error: (400) Bad Request.
  at System.Net.HttpWebRequest.GetResponse()
  at SecureHttp.SecureHttpRequest.PostHttpData(String url, String postData, X509Certificate2 certificate) in y:\HttpRequest.cs:line 718']]></COLUMN>
        </ROW>
        <ROW>
                <COLUMN NAME="COUNT_ERROR"><![CDATA[26]]></COLUMN>
                <COLUMN NAME="BODY_ERROR"><![CDATA[ERROR:РњTC:StatusLastOperation=RequestError Подробная ошибка=' ERROR: StatusLastOperation=ErrorReadingStreamException  Exception РїСЂРё чтении ответа сервера РњРўРЎ. Exception=System.Net.
WebException: The remote server returned an error: (500) Internal Server Error.
  at System.Net.HttpWebRequest.GetResponse()
  at SecureHttp.SecureHttpRequest.PostHttpData(String url, String postData, X509Certificate2 certificate) in y:\HttpRequest.cs:line 718']]></COLUMN>
        </ROW>
</RESULTS>

Пример вывода json, System.Array, count 6:
Код:

{"results":[{"columns":[{"name":"COUNT_ERROR","type":"NUMBER"},{"name":"BODY_ERROR","type":"VARCHAR2"}],"items":
[
{"count_error":10579,"body_error":"ERROR:РњTC:StatusLastOperation=RequestError Подробная ошибка=' ERROR: StatusLastOperation=ErrorReadingStreamException  Exception РїСЂРё чтении ответа сервера РњРўРЎ. Exception=System.Net.We
bException: The remote server returned an error: (400) Bad Request.\r\n  at System.Net.HttpWebRequest.GetResponse()\r\n  at SecureHttp.SecureHttpRequest.PostHttpData(String url, String postData, X509Certificate2 certificate) in y:\HttpRequest.cs:line 718'"}
,{"count_error":27,"body_error":"ERROR:РњTC:StatusLastOperation=RequestError Подробная ошибка=' ERROR: StatusLastOperation=ErrorReadingStreamException  Exception РїСЂРё чтении ответа сервера РњРўРЎ. Exception=System.Net.WebE
xception: The remote server returned an error: (500) Internal Server Error.\r\n  at System.Net.HttpWebRequest.GetResponse()\r\n  at SecureHttp.SecureHttpRequest.PostHttpData(String url, String postData, X509Certificate2 certificate) in y:\HttpRequest.cs:line 718'"}
]}]}


Далее это добро я хочу записать в другую базу, где есть эти же два столбца. Для этого мне нужно правильно распознать получаемые данные, а это два столбца и сколько то строк. Данные преобразовать в DataTable. Воспользоваться Invoke-SQLiteBulkCopy.
Не могу никак разобрать данные и преобразовать в DataTable.

Griboed0ff 15-03-2022 21:27 2981730

Пока только получилось сохранить данные в файл csv и после импорта уже разбирать его.
Скрипт
Код:

$datasource = "D:\base_dw.db"
$file = "D:\123.csv"
[string]$time= "Table_" + [int64](([datetime]::UtcNow)-(get-date "1/1/1970")).TotalSeconds

$comand = @"
drop table qqqqqqq;
create global temporary table qqqqqqq
( ncount number,
  rerror varchar (1000))
  on commit delete rows;
DECLARE
rrrr  rta.list.request_id%TYPE;
begin   
  dbms_output.enable (buffer_size => NULL); 
  FOR jj IN (select distinct result_detail from rta.list where system_date>='16.02.2022' and operation_error='ERROR')
  loop
      select count(result_detail) into rrrr from rta.list where result_detail=jj.result_detail and system_date>='16.02.2022';
      Insert into qqqqqqq(ncount,rerror) values (rrrr,jj.result_detail);
      --dbms_output.put_line(rrrr||'::::'||jj.result_detail);
  end loop;
end;
/
select * from qqqqqqq;
"@


$comand | D:\sqlcl\bin\sql.exe -silent -oci **** | Where {$_} |Out-File $file

    # Создаем столбцы и указываем типы данных
    $table = New-Object system.Data.DataTable 'TestDataTable1'
    $newcol = New-Object system.Data.DataColumn SYSDATETIME,([datetime]);
    $table.columns.add($newcol)
    $newcol = New-Object system.Data.DataColumn COUNT_ERROR,([int]);
    $table.columns.add($newcol)
    $newcol = New-Object system.Data.DataColumn BODY_ERROR,([string]);
    $table.columns.add($newcol)
   
       
    # Записываем инфу в ранее созданные столбцы из CSV
    $csv = Import-CSV $file -delimiter ","
    $csv | ForEach-Object {
        $row = $table.NewRow()
        $row.SYSDATETIME= (get-date).ToString()  #('HH:00:00')
        $row.COUNT_ERROR= ($_.COUNT_ERROR)
        $row.BODY_ERROR= ($_.BODY_ERROR)
        $table.Rows.Add($row)  }

Invoke-SQLiteBulkCopy -DataTable $table  -DataSource $DataSource  -Table "count_error" -force


Может кто знает как можно обойтись без экспорта и импорта файла? Решить все в теле скрипта?

Sham 15-03-2022 22:24 2981738

есть ConvertFrom-Csv. Можно попробовать через переменную.
Код:

$arr = $comand .... (без Out-File)
$csv = $arr -join "`r`n" | ConvertFrom-Csv -Delimiter ','


Griboed0ff 16-03-2022 07:23 2981749

Я ранее пробовал ConvertTo-Csv, но всегда получал, что-то типа:
Код:

"Length"
"40"
"291"
"45"
"211"
"301"
"45"
"209"

А до этого пытался сохранить xml и разобрать его, но он не так прост оказался.
Цитата:

Цитата Sham
$arr -join "`r`n" | ConvertFrom-Csv -Delimiter ',' »

Не понял что за магия с джоинами, но работает! Спасибо!

Griboed0ff 16-03-2022 09:42 2981757

Осталось победить кодировку. Она ломается два раза, сначала при выгрузке из одной базы, а потом уже после загрузки в другую. В самом PL/SQL Developer все круто, но консольные утилиты все ломают.
Что изначально:
Код:

ERROR:РТТ:StatusLastOperation=RequestError Подробная ошибка=' ERROR: StatusLastOperation=ErrorReadingStreamException  Exception при чтении ответа сервера РТТ. Exception=System.Net.WebException: The remote server returned an error: (400) Bad Request.
  at System.Net.HttpWebRequest.GetResponse()
  at SecureHttp.SecureHttpRequest.PostHttpData(String url, String postData, X509Certificate2 certificate) in y:\HttpRequest.cs:line 718'

После получения данных в PowerShell:
Код:

ERROR:РњTТ:StatusLastOperation=RequestError Подробная ошибка=' ERROR: StatusLastOperation=ErrorReadingStreamException  Exception РїСЂРё чтении ответа сервера РњРўРЎ. Exception=System.Net.WebException: The remote server returned an error: (400) Bad Request.
  at System.Net.HttpWebRequest.GetResponse()
  at SecureHttp.SecureHttpRequest.PostHttpData(String url, String postData, X509Certificate2 certificate) in y:\HttpRequest.cs:line 718'

В итоговой базе:
Код:

ERROR:╨ЬTТ:StatusLastOperation=RequestError ╨Я╨╛╨┤╤А╨╛╨▒╨╜╨░╤П ╨╛╤И╨╕╨▒╨║╨░=' ERROR: StatusLastOperation=ErrorReadingStreamException  Exception ╨┐╤А╨╕ ╤З╤В╨╡╨╜╨╕╨╕ ╨╛╤В╨▓╨╡╤В╨░ ╤Б╨╡╤А╨▓╨╡╤А╨░ ╨Ь╨в╨б. Exception=System.Net.WebException: The remote server returned an error: (400) Bad Request.
  at System.Net.HttpWebRequest.GetResponse()
  at SecureHttp.SecureHttpRequest.PostHttpData(String url, String postData, X509Certificate2 certificate) in y:\HttpRequest.cs:line 718'


Griboed0ff 16-03-2022 12:27 2981766

Кодировка побеждена
Код:

function ConvertTo-Encoding ([string]$From, [string]$To){
        Begin{
                $encFrom = [System.Text.Encoding]::GetEncoding($from)
                $encTo = [System.Text.Encoding]::GetEncoding($to)
        }
        Process{
                $bytes = $encTo.GetBytes($_)
                $bytes = [System.Text.Encoding]::Convert($encFrom, $encTo, $bytes)
                $encTo.GetString($bytes)
        }
}

В ISE
Код:

$arr = $comand ....| ConvertTo-Encoding UTF-8 windows-1251
В консоли
Код:

$arr = $comand ....| ConvertTo-Encoding UTF-8 cp866

Sham 16-03-2022 18:36 2981784

Цитата:

Цитата Griboed0ff
что за магия с джоинами »

Сами же пишите, что изначально в массиве неправильный csv. Чтобы правильно распарсить csv-строки по объектам ему нужен исходный текст целиком с переносами строк.


Время: 23:48.

Время: 23:48.
© OSzone.net 2001-