SSRS: Interaktywne sortowanie kolumny

2020-09-01

W raporcie tworzonym w SSRS można zezwolić użytkownikowi na wykonywanie dowolnego sortowania wg wybranej kolumny. Kolumna ta nie musi pochodzić bezpośrednio z bazy danych – może powstawać jakkolwiek w data set. W tym celu wystarczy tylko odpowiednio zmienić właściwości kolumny:

By Rafał Kraik in SSRS

Windows: Włączanie historii harmonogramu zadań

2020-08-20

Task Scheduler lub po polsku Harmonogram Zadań służy do planowania i wykonywania powtarzalnych zadań na systemie. Narzędzie samo w sobie jest bardzo użyteczne… o ile działa… A jak nie działa? Do sprawdzenia wyników, warto by zajrzeć do historii wywołań takiego zadania. Historię można znaleźć przechodząc do określonego zadania w Harmonogramie. Problem w tym, że często ta historia jest wyłączona:

Włączenie historii jest proste, ale trzeba bardzo uważnie klikać myszką. Obawiam się, że projektanci aplikacji mogli by nieco poprawić usability tego programu. Należy kliknąć prawym przyciskiem myszy na „Task Scheduler” i wybrać polecenie „Enable All Tasks History”. Zazwyczaj kiedy tam klikasz, tej pozycji nie ma w menu! Skandal! Żeby polecenie było widoczne kliknij najpierw lewym przyciskiem myszy na Task Scheduler. W centralnej części okna pojawi się wtedy podsumowanie statusu zadań (okno startowe programu). Dopiero kolejne kliknięcie spowoduje, że w menu pojawi się poszukiwana opcja.

Po jej wybraniu właściwie od razu będzie można przeglądać historię uruchamianych zadań.

R: nazywanie kolumn macierzy z prefixem

2020-08-13

R pozwala nazywać wiersze i kolumny macierzy. Dość często do nazywania wierszy i kolumn stosowane są pewne stałe, jak np. nazwy miesięcy, nazwy dni tygodnia, albo po prostu numery kolumn/wierszy. A co jeśli chcesz żeby macierz została nazwana czymś w rodzaju:

x_<numer>

Popatrz na kolejny przykład. Najpierw tworzymy macierz m z 12 kolumnami i 1o wierszami

m <- matrix(data=c(1:120), ncol = 12)
m
      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12]
 [1,]    1   11   21   31   41   51   61   71   81    91   101   111
 [2,]    2   12   22   32   42   52   62   72   82    92   102   112
 [3,]    3   13   23   33   43   53   63   73   83    93   103   113
 [4,]    4   14   24   34   44   54   64   74   84    94   104   114
 [5,]    5   15   25   35   45   55   65   75   85    95   105   115
 [6,]    6   16   26   36   46   56   66   76   86    96   106   116
 [7,]    7   17   27   37   47   57   67   77   87    97   107   117
 [8,]    8   18   28   38   48   58   68   78   88    98   108   118
 [9,]    9   19   29   39   49   59   69   79   89    99   109   119
[10,]   10   20   30   40   50   60   70   80   90   100   110   120

Kiedy chcesz nazwać kolumny numerami poprzedzonymi prefiksem x_, wystarczy skonstruować wektor, który z takich danych się składa. Do łatwego zbudowania takiego wektora można wykorzystać paste(), które jako argumenty przyjmuje wartości do połączenia:

colnames(m) <- paste('x_', c(1:12))
m

wynik będzie taki:

      x_ 1 x_ 2 x_ 3 x_ 4 x_ 5 x_ 6 x_ 7 x_ 8 x_ 9 x_ 10 x_ 11 x_ 12
 [1,]    1   11   21   31   41   51   61   71   81    91   101   111
 [2,]    2   12   22   32   42   52   62   72   82    92   102   112
 [3,]    3   13   23   33   43   53   63   73   83    93   103   113
 [4,]    4   14   24   34   44   54   64   74   84    94   104   114
 [5,]    5   15   25   35   45   55   65   75   85    95   105   115
 [6,]    6   16   26   36   46   56   66   76   86    96   106   116
 [7,]    7   17   27   37   47   57   67   77   87    97   107   117
 [8,]    8   18   28   38   48   58   68   78   88    98   108   118
 [9,]    9   19   29   39   49   59   69   79   89    99   109   119
[10,]   10   20   30   40   50   60   70   80   90   100   110   120
By Rafał Kraik in R

SQL: CLR bad przy zaladowaniu CLR

2020-08-06

Oj oj. Nowe funkcjonalnosci sa tak bardzo zachwalane przez MS. Uzyj tego uzyj tamtego. Problem tylko w tym, ze te nowosci czesto sie ze soba gryza albo z czasem sa modyfikowane lub wycofywane (!)

CLR na SQL ma rzeczywiscie szerokie mozliwosci, bo pozwla na korzystanie ze wszelkich funkcji .NET z poziomu SQL. Konfiguracja CLR juz od samego poczatku skladala sie z kilku krokow, a od wersji 2017 zostala jeszcze zmieniona. Tutaj nie znajdziesz pelnego opisu jak konfigurowac CLR, ale wylacznie opis jednego bledu I rozwiazania.

SQL 2016. Baza ma ustawiony parameter TRUSTWORTHY, a jej wlascicielem jest konto XXXX (login domenowy). Do bazy zostal zaladowany CLR z PERMISSION SET UNSAFE. Podczas korzystania z funkcji pojawia sie blad:
Msg 10314, Level 16, State 11, Line 113
An error occurred in the Microsoft .NET Framework while trying to load assembly id 65538. The server may be running out of resources, or the assembly may not be trusted with PERMISSION_SET = EXTERNAL_ACCESS or UNSAFE. Run the query again, or check documentation to see how to solve the assembly trust issues. For more information about this error:
System.IO.FileLoadException: Could not load file or assembly 'xxxxxxxxx, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null’ or one of its dependencies. An error relating to security occurred. (Exception from HRESULT: 0x8013150A)
System.IO.FileLoadException:
   at System.Reflection.RuntimeAssembly._nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, RuntimeAssembly locationHint, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks)
   at System.Reflection.RuntimeAssembly.InternalLoadAssemblyName(AssemblyName assemblyRef, Evidence assemblySecurity, RuntimeAssembly reqAssembly, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks)
   at System.Reflection.RuntimeAssembly.InternalLoad(String assemblyString, Evidence assemblySecurity, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean forIntrospection)
   at System.Reflection.RuntimeAssembly.InternalLoad(String assemblyString, Evidence assemblySecurity, StackCrawlMark& stackMark, Boolean forIntrospection)
   at System.Reflection.Assembly.Load(String assemblyString)

Najwazniejsza czesc to An error relating to security occurred. Co ciekawe ten sam assembly zaladowany do innej bazy, ktrej wlascicielem jest sa – dziala! Chwila refleksji I czytania dokumentacji pozwolila ustalic, ze to wlasciciel bazy danych musi miec odpowiednie uprawnienie:

use [master]
GO
GRANT UNSAFE ASSEMBLY TO [DOMAIN\LOGIN] 
GO

U mnie dziala, ale warto pamietac, ze w nowszych systemach assembly nalezy podpisywac, a do certyfikatu tworzyc stowarzyszony login, ale to zdecydowanie cos na dluzszy artykul…

By Rafał Kraik in SQL

Linux: Zmiana adresu IP na stały

2020-07-30

Linux to świetny system na Workstation, ale jeszcze lepszy na serwer. W przypadku serwerów często decydujemy się na zmianę adresu IP na stały. Oto jak to zrobić z wykorzystaniem polecenia nmcli:

nmcli connection modify <connection_profile_name> ipv4.method manual \
ipv4.address <new_ip_address/mask> ipv4.gateway <gateway_address> \
ipv4.dns <dns_address>

np.

nmcli connection modify PROD  ipv4.method manual \
ipv4.address 192.168.137.100/24 ipv4.gateway 192.168.137.1 \
ipv4.dns 192.168.137.1

Zazwyczaj największym „problemem” jest odnalezienie nazwy profilu połączenia, a tymczasem jest to proste 🙂

Polecenie

ip address

wyświetla urządzenia interfejsów sieciowych i ich aktualne adresy IP. Z tego polecenia należy zapamiętać nazwę urządzenia (np eth0)

Polecenie

nmcli connection show

wyświetla nazwy profili przypisane do poszczególnych urządzeń. Wystarczy więc odczytać nazwę profilu połączenia stowarzyszoną z urządzeniem sieciowym (np. Wired Connection 1)

Jeśli nazwa profilu zawiera spacje, to w poleceniu nmcli należy te spacje poprzedzać znakiem \ (backslash), np. Wired\ Connection\ 1

Po wykonaniu w/w polecenia nmcli, nowa konfiguracja zostaje zapisana w plikach konfiguracyjnych Network Managera, ale nie jest ona od razu aktywowana. W celu ponownego zastosowania już nowej konfiguracji należy podnieść interfejs sieciowy:

sudo nmcli connection up PROD
By Rafał Kraik in Linuxy

Nowy kurs: Administrator Linux – Instalacja i konfiguracja

2020-07-22

Tym razem rozbudowałem ścieżkę edukacyjną Linux. Po kursie Linux-a  dla początkujących pora na pierwszy kurs administratora Linux-a!

Kurs Administrator Linux: Instalacja i konfiguracja składa się z głównych pięciu elementów:

  1. Instalacja systemu
  2. Konfiguracja sieci
  3. Konfiguracja usług systemu przez systemd
  4. Konfiguracja i zarządzanie dyskami
  5. Proces bootwania i konfiguracja GRUB

Jak zwykle starałem się dostarczyć maksymalnie dużo przykładów, zadań do samodzielnego rozwiązania (z odpowiedziami) i quizów. Zapraszam!

By Rafał Kraik in Aktualności

Helpdesk: Błąd Application failed to start. Contact *** for details. Error code 662

2020-07-18

Aplikacja jest dostępna  na CDROM, a właściwie była, bo płyta została przekopiowana z CDROM na dysk. Po uruchomieniu startera aplikacji niestety zamiast okienka aplikacji wyskakiwał błąd:

Application failed to start. Contact *** for details. Error code 662

Aplikacja nie była uruchamiana już chyba od ponad roku, więc właściwie przyczyną mogło być wszystko – zaczynając od odinstalowania wymaganego komponentu, instalacja konfliktowej łatki windows itp. Tym razem było jednak inaczej. Aplikacja oczekiwała określonej daty na komputerze – to ciekawe, bo podczas zakupu programu nie było mowy o tym, że będzie on działać tylko przez określony czas! Przy okazji trzeba pamiętać:

  • do zmiany czasu wymagane jest uprawnienie administratora (albo odpowiednie prawo)
  • zmiana czasu jest co do zasady złym pomysłem, bo może wtedy przestać działać automatyczne przywracanie systemu, kopie zapasowe, uwierzytelnienie certyfikatami i wiele wiele innych rzeczy, więc jeśli już zmieniać czas to robić to na jak najkrótszą chwilę
  • aplikacja sprawdza czas tylko podczas uruchomienia, a nie w czasie pracy, więc wystarczy zmieniać czas na kilka/kilkanaście sekund podczas startu
  • czas może wrócić do  poprzednich ustawień, jeśli synchronizacja jest włączona

Zmiana czasu w sposób interaktywny jest męczącą, trzeba się przeklikać przez wiele okienek, dlatego wymyśliłem, że zrobię to skryptem uruchamianym „jako administrator”. Pomysł jest następujący:

  • wyliczymy czas 2 lata wstecz –  gdyby to było za mało, to można zmienić na 3, 4 itd. lub przypisać datę na stałe
  • zmienimy ustawienia synchronizacji czasu w bezpośrednio rejestrze na „NoSync”
  • przestawimy datę
  • uruchomimy aplikację – zmień ścieżkę na właściwą
  • zatrzymamy skrypt na np. 15 sekund – można zmienić zależnie od potrzeb
  • potem wrócimy do starej daty. Będzie ona o 15 sekund nieaktualna, ale ponieważ za chwilę włączymy synchronizację czasu, to problem rozwiąże się sam, a 15 sekund nie jest aż takim problemem. Ewentualnie w tym miejscu można by dodać 15 sekund lub nawet uruchomić ręczną synchronizację czasu
  • ostatni krok, to włączenie synchronizacji bezpośrednio w rejestrze na „NTP”
# przesun czas o 2 lata wstecz
# uruchamiaj jako administrator

$oldDate = Get-Date
$newDate = $oldDate.AddYears(-2)

Set-ItemProperty HKLM:\SYSTEM\CurrentControlSet\services\W32Time\Parameters -Name "Type" -Value "NoSync"
set-date -Date $newDate

Start-Process -FilePath D:\MY_FOLDER\MY_APPLICATION.EXE

Start-Sleep -Seconds 15
set-date -Date $oldDate
Set-ItemProperty HKLM:\SYSTEM\CurrentControlSet\services\W32Time\Parameters -Name "Type" -Value "NTP"

I to wszystko! Aplikację należy uruchomić przy pomocy skrótu, jako administrator. Aplikacja przy starcie odczytuje zmieniony czas i przechodzi do kolejnych kroków uruchomienia, a gdy już działa… czas wraca do poprzedniej wartości

By Rafał Kraik in Helpdesk