Różnica między JOIN i LEFT JOIN

Automatyzacja PowerShell i SFTP

Operacja złączenia JOIN

Operacja złączenia wewnętrzego JOINPełna nazwa to INNER JOIN, ale jest to operacja tak popularna, że rozsądne było skrócenie tego do jednego tylko słowa kluczowego JOIN. Reasumując: INNER JOIN to to samo co JOIN. w algebrze relacyjnej odpowiada tzw. złączeniom Theta (θ). Wynikiem złącznia dwóch zbiorów A(a1, a2,...,an) i B(b1, b2,...,am), jest zbiór wszystkich par, C, zawierający każdy atrybut z obu zbiorów wejściowych, C(a1, a2,...,an, b1, b2,...,am) i spełniających predykat złączeniaPredykat należy rozumieć jako warunek złączenia, podawany w sekcji ON i mogący zwierać praktycznie dowolne warunki logiczne..

Można takie złączenie zdefiniować nieco inaczej, programistycznie. Złączenie A JOIN B ON W, gdzie A, B to zbiory wejściowe, W to dowolny warunek, możemy wyliczyć następująco:

Dla każdego wiersza (a1, a2,...,an) ze zbioru A:
    Dla każdego wiersza (b1, b2,...,am) ze zbioru B:
        Jeżeli spełniony jest warunek W(A, B)
            Zwróć (a1, a2,...,an, b1, b2,...,am)

Powyższy algorytm jest raczej fizyczną implementacją niż definicją, ale pomaga zrozumieć ogólną zasadęJest to jedna z najprostszych metod implementacji, tzw. LOOP JOIN. Dwa inne popularne algorytmy to HASH JOIN i MERGE JOIN..

Jeszcze inną metodą pokazania złączenia jest konkretny przykład. Jest to jednocześnie moja ulubiona metoda. Popatrzmy na przykładowe dwie tabele reprezentujące pracownika i przypisane do niego zadania:

CREATE TABLE Employee
(
    ID int CONSTRAINT PK_Employee_ID PRIMARY KEY,
    FirstName nvarchar(20) NOT NULL,
    LastName nvarchar(20) NOT NULL
)

INSERT Employee VALUES (1, 'Jan', 'Byk'), (2, 'Anna', 'Kot'), (3,'Ewa','Lis')

CREATE TABLE Task
(
    ID int IDENTITY CONSTRAINT PK_Task_ID PRIMARY KEY,
    Name nvarchar(20) NOT NULL,
    Assignment int CONSTRAINT FK_Task_Employee FOREIGN KEY REFERENCES Employee(ID)
)

INSERT Task VALUES ('Fix issue', 1),('Eat something',1),('Handle data', 3),('Do some stuff', NULL)

Oraz na złączenie:

SELECT E.FirstName, E.LastName, E.ID, T.Assignment, T.Name
FROM Employee E
JOIN Task T ON T.Assignment=E.ID

Wynikiem pokazanej operacji będzie taka oto tabela:

FirstNameLastNameIDAssignmentName
JanByk11Fix issue
JanByk11Eat something
EwaLis33Handle data

Celowo pokazałem dwie kolumny złączenia obok siebie. Na nich operuje predykat. Jeżeli są równe, mamy dopasowanie. Anna Kot nie jest wyświetlana, bo nie ma zadania wskazującego na numer 2. Do some stuff również nie ma wskazania na żadniego z pracowników i też jest odrzucone. Jan Byk ma dwa dopasowania, dlatego dwa wiersze z Janem Bykiem pojawiły się w zbiorze wynikowym.

Zobacz cały wpis: Różnica między JOIN i LEFT JOIN

Kategoria:SQL Server

SFTP w PowerShell

Automatyzacja PowerShell i SFTP

O SFTP słów kilka

SFTP, rozwijany jako SSHSSH, Secure Shell, protokół zapewniający bezpieczną komunikację na niezabezpieczonej sieci. Zwykle sprowadza się to do zdalnej konsoli pozwalającej na wykonywanie poleceń. File Transfer Protocol, Secure File Transfer Protocol lub, popularnie, bezpieczny FTP. Tak jak FTP, tak i SFTP służy do zarządzania plikami. Z tą różnicą, że SFTP zapewnia bezpieczny kryptograficznie transfer.

Aplikacje klienckie

Do zarządzania zasobami poprzez SFTP w środowisku Windows można stosować wiele narzędzi. Jest FileZilla, graficzne narzędzie dostępne na wielu platformach (Windows, Linux). Jest PuTTY, szerzej znany jako klient SSH, ale dostępny także dla SFTP pod nazwą PSFTP (psftp.exe). Jest w końcu, moim zdaniem najpopularniejszy i najwygodniejszy w obsłudze, WinSCP. Najwygodniejszy, bo posiada graficzny interfejs użytkownika. Elastyczny, bo umożliwia wykonywanie zadań z linii poleceń. Co więcej, biblioteka, dostępna dla środowiska .NET, może być dołączana do własnych aplikacji i, co najbardziej teraz istotne, ładnie integrująca się z PowerShell.

Wymagania wstepne

Aby ustanowić połączenie SFTP musimy pobrać biliotekę WinSCPnet.dll. Jeżeli mamy już zainstalowaną plikację WinSCP, możemy ją znaleźć w katalogu instalacyjnym. W moim przypadku jest to:

C:\Program Files (x86)\WinSCP\WinSCPnet.dll

Jeżeli nie mamy WinSCP, można tę bibliotekę pobrać z Internetu, najlepiej bezpośrednio ze strony WinSCP. W momencie pisania tego akapitu była to podstrona Downloading and Installing WinSCP .NET Assembly.

Ostatni etap to pobranie parametrów połączenia:

  • Adresu serwera z plikami
  • Nazwy użytkownika
  • Hasła użytkownika
  • Skrótu klucza hosta

Adres, login i hasło nie wymagają wyjaśnień i powinniśmy je dostać od administratora. Ta ostatnia wartość może być zakakująca, ale i tę wartość powinien nam dać administrator. Więcej informacji można znaleźć na stronie WinSCP. Poniżej zamieszczam tylko krótki wycinak:

You should get an SSH host key fingerprint along with your credentials from a server administrator. Knowing the host key fingerprint and thus being able to verify it is an integral part of securing an SSH connection. It prevents man-in-the-middle attacks.

Wartość ta jest pochodną publicznego klucza serwera SFPT i jest taka sama dla wszystkich użytkowników. Jeżeli administrator tej wartości nie poda, można ją skopiować od innych użytkowników - będzie zawsze taka sama.

PowerShell

Po uzyskaniu wszystkich parametrów, samo połączenie jest już proste:

Add-Type -Path 'WinSCPnet.dll'
$sessionOptions = New-Object WinSCP.SessionOptions -Property @{
    Protocol = [WinSCP.Protocol]::Sftp
    HostName = "myserver.com"
    UserName = "MyLogin"
    Password = "MyP@ssłorD"
    SshHostKeyFingerprint = "ecdsa-sha2-nistp256 256 23:22:6f:dd:23:de:12:90:ff:ab:09:18:28:11:90:0e"
}

$session = New-Object WinSCP.Session
try
{
    $session.Open($sessionOptions)
    $session.ListDirectory("/subfolder").Files | ft
}
finally
{
    $session.Dispose()
}

W wyniku wykonania tego skryptu, oczywiście w zależności od zawartości systemu plików, możemy otrzymać mniej więcej taką odpowiedź:

Name      FullName             FileType Length Length32 LastWriteTime       FilePermissions Owner Group IsDirectory
----      --------             -------- ------ -------- -------------       --------------- ----- ----- -----------
Plik1.txt /subfolder/Plik1.txt        -   1315     1315 2018-06-21 09:22:21 rw-rw-r--       1017  100         False
FOLDER1   /subfolder/FOLDER1          d      0        0 2018-06-26 10:16:24 rwxr-xr-x       1017  100          True
FOLDER2   /subfolder/FOLDER2          d      0        0 2016-09-28 16:53:55 rwxr-xr-x       1017  100          True
(kolejne pozycje)

W pokazanym przykładzie użyta została metoda ListDirectory. Po otwarciu sesji i przed jej zamknięciem do naszej dyspozycji pozostaje znacznie więcej metod: GetFiles, PutFiles, RemoveFiles czy CreateDirectory. Dzięki mechanizmowi podpowiadania składni wystarczy wpisać $session, potem kropkę i uzyskać całą listę możliwości. Wszystko opisane jest w dokumentacji, ale w większości przypadków same nazwy dość jasno określają przeznaczenie metod.

Zobacz cały wpis: SFTP w PowerShell

Kategoria:PowerShell

Oracle 32-bit i 64-bit na jednym serwerze

Dwie wersje bibliotek - x86 i x64 - na jednym komputerze

Źródło problemu

Przejście procesorów z architektury 32-biowej na 64-botową niesie za sobą szereg konsekwencji. To co w głównej mierze decyduje o braku możliwości pogodzenia bibliotek 32-bitowych i 64-bitowych to rozmiar wskaźnika i możliwości adresowania poszczególnych obszarów pamięci. 32-bitowy wskaźnik nie jest w stanie zaadresować 64-bitowej przestrzeni adresowej, 64-bitowy wskaźnik może wskazywać adres niemożliwy do osiągnięcia przez wskaźnik 32-bitowy.

Tryby kompilacji .NET

Kompilator .NET pozwala wygenerować pliki wykonywalne (ang. PE, zob. format Portable Executable) oraz biblioteki w trzech podstawowych trybach:

  • x86 - pliki z kodem wykonywalnym przeznaczonym dla architektury 32-bitowej,
  • x64 - pliki z kodem wykonywalnym przeznaczonym dla architektury 64-bitowej,
  • AnyCPU - pliki z kodem zarządzanym, niezależnym od architektury, język pośredni (ang. CIL, Common Intermediate Language).

O ile dwa pierwsze tryby mają jasno określoną strukturę, o tyle ten ostatni tryb w przypadku wywołania funkcji natywnych (Win API, COM, itp.) musi samodzielnie obsłużyć różnice w adresacji.

Kombinacje bitowości i ich zgodność

Platforma .NET podczas wczytywania bibliotek zależnych sprawdza, czy istnieje zgodność wersji w następujący sposób:

System 32-bitowy

  • Any CPU uruchamiane jest jako proces 32-bitowy, może wczytywać zależności Any CPU oraz 32-bitowe. Generuje wyjątek BadImageFormatException podczas wczytywania zależności 64-bitowej.
  • x86 uruchamiane jest jako proces 32-bitowy, może wczytywać zależności Any CPU oraz 32-bitowe. Generuje wyjątek BadImageFormatException podczas wczytywania zależności 64-bitowej.
  • x64 Zawsze generuje wyjątek BadImageFormatException.

System 64-bitowy

  • Any CPU uruchamiane jest jako proces 64-bitowy, może wczytywać zależności Any CPU oraz 64-bitowe. Generuje wyjątek BadImageFormatException podczas wczytywania zależności 32-bitowej.
  • x86 uruchamiane jest jako proces 32-bitowy, może wczytywać zależności Any CPU oraz 32-bitowe. Generuje wyjątek BadImageFormatException podczas wczytywania zależności 64-bitowej.
  • x64 uruchamiane jest jako proces 64-bitowy, może wczytywać zależności Any CPU oraz 64-bitowe. Generuje wyjątek BadImageFormatException podczas wczytywania zależności 32-bitowej.

Zależność poza trybem zarządzanym z niezgodnośią bitów

O ile aplikacja w całości pisana w trybie zarządzanym (platforma .NET) działa bezproblemowo w trybie ANY CPU w obu architekturach sprzętowych, o tyle korzystanie z komponentów zewnętrznych wymaga ostrożności. Np. w przypadku sterownika Oracle (Oracle Client) niezgodność bitów może powodować komunikat podobny do poniższego:

Attempt to load Oracle client libraries threw BadImageFormatException. This problem will occur when running in 64 bit mode with the 32 bit Oracle client components installed.

Możliwość uruchamiania dwóch wersji na jednym fizycznym komputerze

Instalując sterownik 32-bitowy Oracle pozwalamy na działanie aplikacji tylko w trybie 32-bitowym. Instalując sterownik 64-bitowy pozwalamy na pracę tylko w trybie 64-bitowym. Co zrobić gdybyśmy zechcieli testować i uruchamiać aplikacje w dwóch różnych trybach? Można zastosować dokładnie ten sam mechanizm, który jest stosowany przez Windows.

Zobacz cały wpis: Oracle 32-bit i 64-bit na jednym serwerze

Kategoria:PowerShellWindows

Informacja o pliku wykonywalnym 32/64 bit - PowerShell

Zarządzanie bitowością aplikacji

Ikona mikroprocesora

Procesory 64-bitowe pojawiły się już dawno. Dawno też zaczęły się pojawiać aplikacje 64 bitowe. Na tyle dawno, że obsługa przez systemy operacyjne 64-bitowych procesorów oraz aplikacje kompilowane na 64-bitowe systemy wydaje się naturalna. Ale...

Świat informatyki nie jest jednak tak prosty jak to się architektom wydaje. Aby zapewnić wsparcie starszych aplikacji 32-bitowych 64-bitowe systemy operacyjne pozwalają uruchamiać aplikacje w trybie zgodności i jest to jedna strona. Druga strona to twórcy aplikacji, którzy celowo tworzą aplikacje 32-bitowe aby dało się je uruchamiać również na starszych systemach operacyjnych. W komputerach domowych problem może pozostać niezauważony, a nawet zauważony - zwykle jest ignorowany. W ostateczności pobiera się z Internetu inną wersję pliku. W dużych rozwiązaniach informatycznych tak łatwo nie jest. Jeden plik wykonywalny o nieprawidłowej "bitowości" może sprawić, że całe, nierzadko skomplikowane rozwiązanie, nie uruchomi się. Otrzymamy zwykle dziwne komunikaty postaci Bad image format lub wyjątki BadImageFormatException lub (Murphy był optymistą) jakieś numerki wyglądające jak wytworzone generatorem liczb pseudolosowych.

Nie jest to najczęściej wina systemu operacyjnego tylko konkretnej aplikacji. Plik wykonywalny może być 32-bitowy a jedna z bibliotek 64-bitowa, plik wykonywalny może być 64-bitowy, kilkadziesiąt bibliotek również 64-bitowych a jakis jeden, jedyny 32-bitowy. Nie ma to znaczenia. To nie demokracja, że decyduje większość. Tu liczy się jednomyślność.

Co możemy z tym zrobić? Musimy do tej jedności doprowadzić. Zanim jednak doprowadzimy, musimy takie pliki zlokalizować.

Pobieranie informacji z nagłówka pliku

Pliki *.exe i *.dll nie są tylko ciągiem instrukcji procesora połączonych z danymiTaką strukturę ma plik .com.. Pliki wykonywalne w Windows mają swoją określoną strukturę, która zdefiniowana jest przez format zwany PE (Portable Executable). I znów - wszystko nie jest takie łatwe jak się na początku wydaje. Aby zapewnić zgodnośc wstecz, format ten osadzony jest w innym formacie zwanym MZ (Mark Zbikowski, jeden z twórców DOS). W czasie pisania tego tekstu obecnie wspierane wersje Windows prawie całkowicie ignorują część zawartą w sekcji MZ rozpoczynając interpretację od sekcji PEW praktyce należy zweryfikować poprawność nagłówka (w szczególności dwa bajty zawierające znaki M i Z) oraz wartość wskazującą położenie nagłówka PE (zapisany na czterech bitach i rozpoczynający się na 60 bajcie nagłówka MZ)..

Nagłówek PE rozpoczyna się, a jakże, od dwóch liter P i E, po których występują dwa zerowe bajty. Kolejne dwa bajty określają architekturę procesora:

Bajty (szesnastkowo)Architektura
0x014cx86
0x0200Intel Itanium
0x8664x64

Mogą się tam pojawić jeszcze inne wartości (ARM, Hitachi - odsyłam do specyfikacji formatu PE), ale w środowisku Windows raczej się nie pojawią i nie będą uruchamiane.

To absolutne minimum jakie trzeba wiedzieć, aby dobrać się do informacji o tym, czy plik skompilowany został jako 64-bitowy czy 32-bitowy. Informacja oczywiście dotyczy plików wykonywalnych w środowisku Windows.

Przykładowa implementacja w PowerShell

Uznałem, że takie badania "bitowości" bardziej kwalifikują się do prac administracyjnych. Stąd wybór narzędzia. Przepisanie tego na C++, C# i inne języki powinno być łatwe. Pełny listing zaprezentowano poniżej:

Zobacz cały wpis: Informacja o pliku wykonywalnym 32/64 bit - PowerShell

Kategoria:PowerShellWindows

Pobieranie tabeli z Excela w PowerShell

Najczęściej używane skrypty PowerShell w pracy programisty - ikona konsoli

Tabele w Excelu

Powershell posiada mnóstwo komponentów do importu i eksportu z różnych źródeł danych. To przecież nie tylko zwykłe tekstowe pliki, ale także pliki html (ConvertTo-Html), pliki JSON (ConvertTo-Json, ConvertFrom-Json), pliki CSV (ConvertFrom-Csv, ConvertTo-Csv, Export-Csv, Import-Csv). Wymagania biznesowe często prowadzą jednak w innym kierunku - w kierunku plików bardziej skomplikowanych w strukturze i mniej nadających się do wymiany danych. Analiza frekwencji potrzeb doprowadziła mnie do wniosku, że bardzio potrzebny okazuje się komponent do importu z pliku Excela - *.xlsx. Problem jednak w tym, że w pliku xlsx może być wiele różnych arkuszy, na każdym z arkuszy kilka bloków z danymi. Trudno wymyślić komponent, który pozbiera wszystkie te dane i wyświetli w jakiś łatwy do dalszej analizy i przetwarzania sposób.

Dane biznesowe prezentowane są zwykle w postaci tabelarycznej, a naturalną ich reprezentacją w Excelu są - a jakże - tabele.

Komponent do importu pliku xlsx

Komponent będzie się nazywał, podobnie jak ma to miejsce w przypadku pliku CSV, Import-ExcelTable (poprzez analogię do wymienionego juz Import-Csv). O ile plik CSV zawiera tylko jedną tabelę (tj. jedną porcję danych), o tyle plik *.xlsx może tych niezależnych porcji mieć więcej. Jak już wspomniałem, mogą to być dane na dowolnym arkuszu i w dowolnej tabeli na tym arkuszu. W najprostszej wersji komponentu wszystkie te parametry będą wymagane. W wersji uproszczonej można założyć, że o ile nie podamy konkretnego arkusza, wybrany zostanie pierwszy z brzegu. Podobnie tabele - jeżeli jakieś są, wybrana zostanie pierwsza w kolejności.

Implementacja komponentu

Komponent będzie korzystał z obiektów COM instalowanych razem z pakietem Office - Excel.Application. Komponent musi być zainstalowany, a jego wersja zostanie odpowiednio wybrana - w zależności od wskazań w rejestrze systemowym.

Popatrzmy na przykładową implementację funkcji, która jest w stanie odczytać dane z tabeli Excela:

function Import-ExcelTable
{
    Param
    (
        [Parameter(Mandatory=$true)]
        [string]$Path,
        [Parameter(Mandatory=$true)]
        [string]$Sheet,
        [Parameter(Mandatory=$true)]
        [string]$Table
    )
    try {
        $excel = New-Object -ComObject Excel.Application
        $file = (ls $Path).FullName
        Write-Verbose "Opening file $file..."
        $workbook = $excel.Workbooks.Open($file)
        $xlSheet = $excel.Sheets.Item($Sheet)
        $xlTable = $xlSheet.ListObjects.Item($Table)
        $captions = $xlTable.HeaderRowRange.Value2

        $data = $xlTable.DataBodyRange.Value2
        for ($i=1; $i -le $data.GetLength(0); $i++) {
            $obj = @{}
            1..$captions.Count | % { $obj[[string]$captions[1,$_]] = [string]$data[$i,$_] }
            [PSCustomObject]$obj
        }
    } finally {
        $workbook.Close()
        $excel.Quit()
        [Runtime.InteropServices.Marshal]::ReleaseComObject($excel) | Out-Null
    }
}

To wszystko, aby w prosty sposób wyświetlić dowolną tabelę.

Zobacz cały wpis: Pobieranie tabeli z Excela w PowerShell

Kategoria:PowerShell

Pobieranie obciążenia procesora w PowerShell

Najczęściej używane skrypty PowerShell w pracy programisty - ikona konsoli

Liczniki wydajności Windows

System Windows posiada liczne mechanizmy pozwalające na monitorowanie zachowań samego systemu, aplikacji i usług. Najbardziej znanym narządziem jest chyba Menedżer zadań. Pozwala on pobrać obciążenie procesora, pamięć zajętą przez poszczególne procesy czy obciążenie karty sieciowej. Jest to z pewnoscią doskonałe narzędzie dla użytkowników, którzy chcą szybko zobaczyć stan systemu. Istnieją jednak inne narzędzia, które znacznie łatwiej automatyzować. Są to liczniki wydajności. Liczniki wykorzystywane są, tak jak Menedżer zadań, w celu udostępnienia informacji o systemie, aplikacjach, usługach i wskazują, jak te komponenty sobie radzą. Pozwala to wskazać słabe elementy, a na dalszym etapie ulepszyć ich działanie. Dane te mogą być pobierane i przetwarzane przez praktycznie każdą aplikację. Nie inaczej jest z PowerShellem.

Pobieranie informacji o zajętości procesora

Aby pobrać dane licznika związane z obciążeniem procesora, a w zasadzie wszystkich procesorów, wystarczy wywołać polecenie Get-Counter z odpowiednią nazwą, np.:

Get-Counter "\Procesor(*)\Czas procesora (%)"

Tu mała uwaga: jeżeli system operacyjny jest w innym języku, nazwy będą inne. Jeżeli wszystko się uda, otrzymamy rezultat podobny do poniższego (przykład obejmuje maszyną z czterema procesorami):

Timestamp                 CounterSamples
---------                 --------------
2017-04-14 18:57:52       \\komputer\procesor(0)\czas procesora (%) :
                          10,5217729945603

                          \\komputer\procesor(1)\czas procesora (%) :
                          13,6072290981962

                          \\komputer\procesor(2)\czas procesora (%) :
                          5,89358883910656

                          \\komputer\procesor(3)\czas procesora (%) :
                          19,7781413054679

                          \\komputer\procesor(_total)\czas procesora (%) :
                          12,450190476247

Przyznam, że nie jest to najwygodniejszy sposób prezentacji informacji. Nie jest też łatwy w późniejszym przetwarzaniu i analizowaniu - zwłaszcza, gdy mamy wiele takich pomiarów. Znacznie wygodniejsza, przynajmniej dla mnie jest forma tabelaryczna, gdzie każdy z procesorów ma swoją kolumnę. Popatrzmy na nieco bardziej złożony skrypt:

Get-Counter "\Procesor(*)\Czas procesora (%)" -MaxSamples 5 | % {
    $obj = [PSCustomObject]@{Time = $_.Timestamp}
    $_.CounterSamples | % {
        $obj | Add-Member -MemberType NoteProperty -Name "Processor($($_.InstanceName))" -Value $_.CookedValue
    }
    $obj
} | ft

Tym razem wyniki będą się prezentowały następująco:

Time                    Processor(0)     Processor(1)     Processor(2)     Processor(3) Processor(_total)
----                    ------------     ------------     ------------     ------------ -----------------
2017-04-14 19:07:23 15,1414729941447 8,96994375735522 10,5128260665526 4,34129682976312  9,74138985705781
2017-04-14 19:07:24  9,2392634503808  12,315898587656  12,315898587656 6,16262831310558  10,0084173042262
2017-04-14 19:07:25  12,315898587656 7,70094588174318 6,16262831310558 7,70094588174318  8,47010959653541
2017-04-14 19:07:26 16,9308512935689 7,70094588174318  12,315898587656 15,3925337249313  13,0850524415014
2017-04-14 19:07:27 21,5458039994817  9,2392634503808 15,3925337249313 20,0074864308441  16,5462743666462

Analiza takiej tabelki wydaje się łatwiejsza.

Zobacz cały wpis: Pobieranie obciążenia procesora w PowerShell

Kategoria:PowerShell

Ostatnie komentarze
Dzieki za rozjasnienie zagadnienia upsert. wlasnie sie ucze programowania :).
Co się stanie gdy spróbuję wyszukać:
SELECT * FROM NV_Airport WHERE Code='SVO'
SELECT * FROM V_Airport WHERE Code=N'SVO'
(odwrotnie są te N-ki)
Będzie konwersja czy nie znajdzie żadnego rekordu?