PoweShell превращение xml в sql

  1. Добавить код в Notepad++
Write-Host 'Вставляйте XML строчки, важно, без пустых строк, когда всё закончилось - жмете Enter в последней строке';
$xml_arr = @()
$inp = $null
While($inp -ne "") 
{
    If ($inp -ne $null) {$xml_arr += $inp.Trim()}
    $inp = Read-Host
}

Write-Host  "______RESULT________`n`n`n`n";


for ($i = 0; $i -le ($xml_arr.length - 1); $i += 1)
{ 
    $str = $xml_arr[$i];
    [xml]$str_xml = $xml_arr[$i];
    $it = $str_xml.FirstChild;
    $tbl=$it.Name;
    $fields = 

    Write-Host "-- SELECT * FROM $($tbl) WHERE ...."

    $select_arr = @()
    $insert_f = @()
    $insert_v = @()
    $upd_arr = @()


    foreach ($field in $it.Attributes )
    {
        $f = $field.Name
        $v = $field.Value

        $select_arr += "'$v' $f"
        $insert_f += $f
        $insert_v += "B.$f"
        $upd_arr += "A.$f = B.$f"

        
    }

    Write-Host "MERGE INTO $tbl A USING
    (SELECT
    $($select_arr -join ", ")
    FROM DUAL) B
ON ($($upd_arr -join " AND "))
WHEN NOT MATCHED THEN
    INSERT ($($insert_f -join ", "))
    VALUES ($($insert_v -join ", "))
WHEN MATCHED THEN
    UPDATE SET $($upd_arr -join ", ");";

}

Write-Host  "---------эту строку не копировать-----`n`nPress any key to continue...";
$null = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown');

2. Сохранить в кодировке cp1251 c расширением ps1

3. Правой кнопкой выполнить в PowerShell

3. Вставляем xml в формате

<table1 field1="val1" field2="val2"/>
<table1 field1="val1" field2="val2"/>

Получаем мерджи для оракла

P.S. но в такой заготовке в блок ON и UPDATE одинаковая последовательность пишется, нужно пройтись руками удалить поля, оставить в ON только ключи, а в UPDATE остальные...
В выходные еще немного заморочился, сделал интерактивный алгоритм, который спрашивает пользователя какие поля ключевые, по ним идет поиск, а остальные идут для UPDATE...

Write-Host 'Вставляйте XML строчки, важно, без пустых строк, когда всё закончилось - жмете Enter в последней строке';
#read multi string
$xml_arr = [ordered]@{}
$inp = $null
$i=0;
While($inp -ne "") 
{
    If ($inp -ne $null) 
    {
        [xml]$str_xml = $inp.Trim();
        $it = $str_xml.FirstChild;
        $tbl=$it.Name;
        #if (!$xml_arr.ContainsKey($tbl))
        if (!$xml_arr.$tbl)
        {
            $xml_arr.add($tbl,@());
        }

        $xml_arr[$tbl]+=$it;

    }
    $inp = Read-Host
}


$out =  "______RESULT________`n`n`n`n";


foreach ($tbl in $xml_arr.keys)
{
    $tbl_arr= $xml_arr[$tbl];
    $table_keys = [ordered]@{};
    $table_fields = [ordered]@{};
    Write-Host "`nНужно определить ключи таблицы $tbl,`nвпишите номера строк через пробел"
    $i=0
    foreach ($field in $tbl_arr[0].Attributes )
    {
        $i+=1;
        Write-Host "[$i] - $($field.Name)";
        $table_fields.add("f_$i",($field.Name));        
    }

    $inp = Read-Host
    $k_nums = $inp -split " ";

    foreach ($k in $k_nums )
    {
          $k = "f_$k";
          if (($k -eq "") -or (!$table_fields.$k))
          {
              continue
          }
    
          $table_keys.add(($table_fields.$k),1);
    }

    $out+= "-- SELECT * FROM $($tbl) WHERE ....`n"
    

    foreach ($it in $tbl_arr)
    {
        $on_arr = $insert_v =$insert_f = $upd_arr = $select_arr = @()
        #attr iteration
        foreach ($field in $it.Attributes )
        {
            $f = $field.Name
            $v = $field.Value

            
            $select_arr += "'$v' $f"
            $insert_f += $f
            $insert_v += "B.$f"
            if ($table_keys.$f)
            {
                $on_arr += "A.$f = B.$f"  
            }  
             else
            {            
                $upd_arr += "A.$f = B.$f"
            }   
        }

    $out+= "MERGE INTO $tbl A USING
    (SELECT
    $($select_arr -join ", ")
    FROM DUAL) B
ON ($($on_arr -join " AND "))
WHEN NOT MATCHED THEN
    INSERT ($($insert_f -join ", "))
    VALUES ($($insert_v -join ", "))
WHEN MATCHED THEN
    UPDATE SET $($upd_arr -join ", ");`n";
    }

}


Write-Host  $out"`n---------эту строку не копировать-----`n`nPress any key to continue...";
$null = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown');
Показать комментарии