2018-03-31
Masz plik na dysku ze zdjęciem lub certyfikatem lub czymkolwiek innym. Plik jest binarny. Jak go wstawić do zmiennej lub do tabeli?
USE tempdb
GO
CREATE TABLE MyBinary(Blob VARBINARY(MAX))
GO
DECLARE @Data VARBINARY(MAX)
SET @Data = (SELECT BulkColumn FROM Openrowset( Bulk 'C:\temp\MyCertificate.cer', Single_Blob) as img)
INSERT MyBinary VALUES(@Data)
GO
W moim przypadku chciałem korzystać z tak zaimportowanego certyfikatu w skrypcie, żeby uruchamiając skrypt na danym systemie nie trzeba było kopiować żadnych dodatkowych plików na czas instalacji. Innymi słowy chciałem mieć zmienną binarną zadeklarowaną w skrypcie. Moja „sztuczka” polegała na wyeksportowaniu danych tabeli MyBinatry i odpowiedniej modyfikacji skryptu. W tym celu:
- Kliknij prawą myszką na bazie danych i wybierze Tasks >> Generate Scripts
- W kreatorze zaznacz tylko tabelę MyBinary
- W następnym oknie kreatora kliknij Advanced i zmień „Schema only” na „Data only”
- W wygenerowanym skrypcie znajdzie się dłuuuuga wartość, która jest reprezentacją kolumny binarnej
Teraz udało mi się więc napisać fragment skryptu w postaci (część binarna jest dla skrócenia wycięta):
DECLARE @DataCert VARBINARY(MAX)
SET @DataCert = (0x308...129)
No dobrze. A jak teraz tego rodzaju zmienną zapisać w postaci pliku binaranego z powrotem na dysku? Skorzystamy z funkcji OLE, które zazwyczaj ze względu na wymogi bezpieczeństwa są wyłaczone, dlatego skrypt najpierw sprawdzi czy opcja 'Ole Automation Procedures’ jest wyłączona, zapamięta to, włączy jeśli trzeba, a na końcu przywróci oryginalne ustawienia. Środkowa część skryptu to kilka kolejnych kroków, które należy wykonać aby dane zapisać na dysku:
DECLARE @DataCert VARBINARY(MAX)
SET @DataCert = (0x308...129)
DECLARE @certPath varchar(50) = 'C:\temp\MyCertificate.cer'
DECLARE @handle int
EXEC sp_OACreate 'ADODB.Stream', @handle OUTPUT;
EXEC sp_OASetProperty @handle, 'Type', 1;
EXEC sp_OAMethod @handle, 'Open';
EXEC sp_OAMethod @handle, 'Write', NULL, @DataCert;
EXEC sp_OAMethod @handle, 'SaveToFile', NULL, @certPath, 2;
EXEC sp_OAMethod @handle, 'Close';
EXEC sp_OADestroy @handle;
IF @initialOLEAutomationOption = 0
BEGIN
EXEC sp_configure 'Ole Automation Procedures', 0
RECONFIGURE WITH OVERRIDE
END
2018-03-26
Jedna prosta komenda:
Get-winEvent -ComputerName $env:COMPUTERNAME -filterHashTable @{logname =’Microsoft-Windows-FailoverClustering/Operational’; id=1641}| ft -AutoSize -Wrap
Właściwie każdy wie, że takie zdarzenia trafiają do loga. Spryt polcecenia polega na wyfiltrowaniu tylko tych zdarzeń, które rzeczywiście są potrzebne.
2018-03-25
Microsoft już dawno temu poinformował o tym, że Profiler nie będzie dalej rozwijany i zaprosił do korzystania z extended events. Rzeczywiście extendend events mają o wiele wiecej możliwości monitorowania aktywności systemu i dodatkowo robią to znacznie wydajniej. Gdyby ktoś jednak nadal nie był przekonany co do stosowania extended events, to może ten wykres go przekona… ?
Wykres prezentuje ilość zdarzeń, które mogą być monitorowane przy pomocy extended events i przy pomocy profilera. Podczas gdy ilość extended events od wersji 2008 powiększyła się 4-krotnie, ilość zdarzeń dla profilera stoi na poziomie 180!
2018-03-25
Kiedy pracujesz z PowerShell, konsola śledzi i zapamiętuje każdy twój ruch. Dzięki temu można przejrzeć listę wykonywanych do tej pory poleceń naciskając strzałkę w górę. Do przejrzenia wcześniej wykonanych poleceń można sie także posłużyć poleceniem
Get-History
Posiadając listę do tej pory wykonanych poleceń, możesz chcieć ponownie uruchomić jedną z nich. Da się to zrobić powołując się na numer komendy w historii uruchamiając
Invoke-History
Tak to działa w praktyce:
Jeśli chcesz tylko pobrać listę komend i umieścić ją w schowku wykonaj:
Get-History | Select -expand CommandLine | clip
2018-03-12
Podczas konfiguracji FILESTREAM dwa razy wykonuje się podobne czynności:
Czy te dwa kroki się powielają? Czy można wykonać jeden a drugiego już nie?
Otóż nie!
Pierwsza część wykonuje fragment konfiguracji systemu operacyjnego, którego nie można wykonać z wewnątrz procesu SQL
Druga część odpowiada za włączenie opcji na poziomie silnika bazy danych
Pierwsza część wymaga uprawnień lokalnego administratora, a druga sysadmina.
To cały powód!
FILESTREAM Configuration and Setup Changes in SQL Server 2008 February CTP
2018-03-12
FileTable to świetny pomysł na przechowywanie w bazie dokumentów (BLOB), które jednocześnie są dla użytkowników widoczne jako zwykłe pliki na systemie plików.
Żeby FileTable (a ogólniej Filestream) mogły działać odpowiednio należy skonfigurować instancję. We właściwościach usługi SQL Server w SQL Server Configuration Manager należy ustawić FILESTREAM (patrz również tutaj)
Konfigurację wykonujemy również w opcjach serwera:
EXEC sp_configure 'filestream access level'
GO
EXEC sp_configure 'filestream access level',2
GO
RECONFIGURE
GO
EXEC sp_configure 'filestream access level
GO
Pora na utworzenie testowej bazy danych
CREATE DATABASE TestFileTable
GO
Ta baza danych musi posiadać FILE GROUP pozwalający na przechowywanie FILESTREAM
USE TestFileTable
GO
ALTER DATABASE TestFileTable ADD FILEGROUP FG_FileStream CONTAINS FILESTREAM
GO
A z kolei ta grupa musi mieć plik. Zadbaj o to aby usługa SQL miała pełne prawa do katalogu nadrzędnego tutaj C:\SQL
ALTER DATABASE TestFileTable ADD FILE (NAME='F_FileStream', FILENAME='C:\SQL\AdventureWorks_FS') TO FILEGROUP FG_FileStream
GO
Baza będzie przechowywać dokumenty w udostępnianym zasobie o nazwie Docs. Dostęp może być tak jak tu FULL (pliki można modyfikować z poziomu aplikacji np Word, Excel itp), READ_ONLY, lub OFF
ALTER DATABASE TestFileTable SET FILESTREAM (NON_TRANSACTED_ACCESS = FULL, DIRECTORY_NAME='Docs')
GO
Teraz można utworzyć tabelę
CREATE TABLE Manuals AS FILETABLE WITH(FILETABLE_DIRECTORY='Manuals')
GO
Jeżeli wkopiujesz pliki do katalogu \\computerName\MSSQLSERVER\Docs\Manuals, to w tabeli Manuals pojawią się rekordy. Podobnie usuwanie tych plików spowoduje, że rekordy będą kasowane
SELECT * FROM Manuals
GO
Tabele FileTable można odnaleźć zaglądając do widoków systemowych:
SELECT * FROM sys.filetables;
GO
SELECT * FROM sys.tables WHERE is_filetable = 1;
GO
SELECT object_id, OBJECT_NAME(object_id) AS 'Object Name'
FROM sys.filetable_system_defined_objects;
GO
SELECT DB_NAME(database_id), non_transacted_access, non_transacted_access_desc
FROM sys.database_filestream_options;
GO
Poziom dostępu do plików w FileTable można zmieniać:
ALTER DATABASE TestFileTable SET FILESTREAM (NON_TRANSACTED_ACCESS = OFF, DIRECTORY_NAME='Docs')
GO
SELECT DB_NAME(database_id), non_transacted_access, non_transacted_access_desc
FROM sys.database_filestream_options;
GO
ALTER DATABASE TestFileTable SET FILESTREAM (NON_TRANSACTED_ACCESS = FULL, DIRECTORY_NAME='Docs')
GO
Jeśli rekord zostanie usunięty z tabeli, to zniknie również plik z katalogu
DELETE FROM Manuals WHERE Name = 'New Text Document (2).txt'
GO
SELECT * FROM Manuals
2018-03-11
Tym razem zajmę się kolejnością wykonywania transakcji. Przeanalizujmy taką sytuację:
- Transakcja A czyta rekord, ale po przeczytaniu rekordu pozostawia na nim lock (czyli np. transakcja pracuje w poziomie izolacji REPEATABLE READ)
- Transkacja B startuje po transakcji A, i zamierza zmodyfikować ten sam rekord
- Transakcja C startuje po transakcji B i zamierza przeczytać ten rekord
Pytanie – w jakiej kolejności wykonają się te transakcje?
- A – B – C, bo w takiej kolejności te transakcje startowały, czy
- A – C – B, bo transakcja C tylko czyta rekord, tak samo jak transakcja A, czyli nie jest w konflikcie z A. B jako transakcja modyfikująca dane i tak musi czekać, więc nie ma problemu, aby „przepuściła” transakcję „C”
Zacznijmy od potwierdzenia, że jeśli mamy tylko A i C, to bez problemu można uruchomić obie transakcje: Czytaj dalej »