MSSQL


Wypisanie komend pod shrink wszystkich plików

W T-SQL (SSMS / SQL Server management studio) wykonujemy polecenie:

SELECT 
      'USE [' + d.name + N']' + CHAR(13) + CHAR(10) 
    + 'DBCC SHRINKFILE (N''' + mf.name + N''' , 0, TRUNCATEONLY)' 
    + CHAR(13) + CHAR(10) + CHAR(13) + CHAR(10) 
FROM 
         sys.master_files mf 
    JOIN sys.databases d 
        ON mf.database_id = d.database_id 

Jeżeli chcemy wykonać shrink bez baz systemowych dopisujemy na końcu:

WHERE d.database_id > 4;

Wynik:

image.png

Kopiujemy wszystko z outputu i wklejamy do nowego query:

image.png

I klikamy wykonaj. Po czym pokaże się w wynikach proces shrinku:

image.png

 

Sprawdzenie aktualnych zadań / zapytań na bazie danych

Wykonujemy w SSMS:

SELECT session_id, command, text FROM sys.dm_exec_requests
CROSS APPLY sys.dm_exec_sql_text(sql_handle)

 

Sprawdzenie ile % bazy danych się odtworzyło

Wykonujemy w SSMS, mając wybraną bazę master:

SELECT 
    [session_id], 
    [command], 
    [percent_complete], 
    DATEADD(MILLISECOND, [estimated_completion_time], GETDATE()) AS [estimated_completion_datetime] 
FROM sys.dm_exec_requests 
WHERE [command] = 'RESTORE DATABASE' 
    AND [start_time] IS NOT NULL; 

Przełączenie bazy danych z [RESTORING...] do open

Wykonujemy w SSMS z wybraną bazą master:

RESTORE DATABASE NazwaBazyDanych 
    WITH RECOVERY; 

Sprawdzenie ostatnich backupów

Uruchamiamy w SSMS z wybraną bazą master

SELECT database_name, backup_finish_date AS last_log_backup 
FROM msdb.dbo.backupset 
WHERE type = 'L' -- L oznacza backup logów 
AND database_name = 'NazwaBazy' -- podaj nazwę bazy danych, której backup chcesz sprawdzić 
ORDER BY backup_finish_date DESC; 

Poprzez wybranie Where type = X wybieramy typ backupu jak poniżej:

           WHEN type = 'D' THEN 'Full Backup'
           WHEN type = 'I' THEN 'Differential Backup'
           WHEN type = 'L' THEN 'Log Backup'
           WHEN type = 'F' THEN 'File Backup'
           WHEN type = 'G' THEN 'Differential File Backup'
           WHEN type = 'P' THEN 'Partial Backup'
           WHEN type = 'Q' THEN 'Differential Partial Backup'

 

 

 

 

Purge informacji o backupach z bazy danych

Uruchamiamy z poziomu SSMS z wybraną bazą master / msdb

use msdb 
go
exec sp_delete_database_backuphistory 'NazwaBazy'  
go 

Sortowanie tabel po rozmiarze

Uruchamiamy w SSMS z wybraną odpowiednią bazą danych:

SELECT
    t.name AS TableName,
    SUM(ps.reserved_page_count) * 8 AS ReservedSpaceKB,
    SUM(ps.used_page_count) * 8 AS UsedSpaceKB
FROM
    sys.tables t
JOIN
    sys.dm_db_partition_stats ps ON t.object_id = ps.object_id
GROUP BY
    t.name
ORDER BY
    SUM(ps.used_page_count) DESC; 

Zajętość poszczególnych tabel w DB

Uruchamiamy w SSMS z wybraną odpowiednią bazą danych:

select top 30 schema_name(tab.schema_id) + '.' + tab.name as [table],  
    cast(sum(spc.used_pages * 8)/1024.00 as numeric(36, 2)) as used_mb, 
    cast(sum(spc.total_pages * 8)/1024.00 as numeric(36, 2)) as allocated_mb 
from sys.tables tab 
join sys.indexes ind  
     on tab.object_id = ind.object_id 
join sys.partitions part  
     on ind.object_id = part.object_id and ind.index_id = part.index_id 
join sys.allocation_units spc 
     on part.partition_id = spc.container_id 
group by schema_name(tab.schema_id) + '.' + tab.name 
order by sum(spc.used_pages) desc; 

 

Przełączanie bazy w tryb read-only

Uruchamiamy w SSMS z wybraną baza master:

USE [master] 
GO 
ALTER DATABASE NazwaBazy SET READ_ONLY WITH NO_WAIT 
GO 

 

Sprawdzenie wszystkich plików, rozmiarów oraz trybu recovery

Uruchamiamy w SSMS z wybraną bazą master:

SELECT  
    d.name AS 'Nazwa bazy danych', 
    d.recovery_model_desc AS 'Tryb odzyskiwania', 
    mf.type_desc AS 'Typ pliku', 
    mf.name AS 'Nazwa pliku', 
    CONVERT(decimal(12,2),mf.size*8/1024.0) AS 'Wielkość pliku (MB)' 
FROM  
    sys.databases d 
JOIN  
    sys.master_files mf ON d.database_id = mf.database_id; 

Shrink rozmiaru logów transakcyjnych

Uruchamiamy w SSMS z wybraną bazą master

Przed samą operacją zaleca się wykonanie backupu full DB. 
Należy również sprawdzić recovery model. 

USE NazwaBazyDanych; 
GO 

-- Zmieniamy tryb recovery na SIMPLE by można było wykonać shrink zapchanego logu
ALTER DATABASE NazwaBazyDanych 
SET RECOVERY SIMPLE; 
GO 

-- Wykonujemy shrink pliku log do 1mb
DBCC SHRINKFILE (NazwaBazyDanych_Log, 1); (1MB) 
GO 

-- Zmieniamy tryb recovery spowrotem na FULL 
ALTER DATABASE NazwaBazyDanych 
SET RECOVERY FULL; 
GO 

Naprawa uszkodzonej przystawki Configuration Manager

W momencie wystąpienia błędu po uruchomieniu: 

Uruchamiamy cmd jako administrator i przechodzimy do shared komponentów MSSQL: 

 cd "C:\Program Files (x86)\Microsoft SQL Server\140\Shared" 

 W tym miejscu uruchomiamy rejestrację komponentów: 

mofcomp sqlmgmproviderxpsp2up.mof 

Po wykonaniu powinniśmy dostać taki komunikat:

Weryfikacja zapchanych logów przy replikacji

Na serwerze MSSQL, "zacięły" się logi. Baza danych nie mogła zwolnić opublikowanych logów z pliku LDF, mimo wykonywanego backupu fulldb oraz backupu logów.  

Nie pomogło rozpięcie replikacji przez "usunięcie" backupów, oraz usuniecie wpisu replikacji z ustawień DB. 

Weryfikujemy czy jakieś zadanie. zatrzymuje coś w plikach LDF (tutaj problemem była nieistniejąca replikacja): 

 SELECT name, log_reuse_wait_desc FROM sys.DATABASES 

image.png

Reset informacji o logach - replikacja 

Wykonujemy Query z poziomu bazy danych z problemem: 

image.png

 EXEC sp_repldone @xactid = NULL, @xact_segno = NULL, @numtrans = 0, @time= 0, @reset = 1 

Query usuwające replikacje: 

USE NazwaBazy; 
GO 

EXEC sp_removedbreplication 'NazwaBazy' 
GO 

CHECKPOINT 
GO 

Oraz usunięcie publikacji bazy danych poprzez: 

use master 
exec sp_replicationdboption @dbname = N'NazwaBazy', @optname = N'publish', @value = N'false' 
GO 

 To powinno sprawić że wykonanie query: 

SELECT name, log_reuse_wait_desc FROM sys.DATABASES 

Zmieni status na poprawny 

image.png

 

Sprawdzenie co blokuje przełączanie trybu bazy po stronie silnika

Wykonujemy z poziomu SSMS z wybraną bazą master:

select 
    l.resource_type, 
    l.request_mode, 
    l.request_status, 
    l.request_session_id, 
    r.command, 
    r.status, 
    r.blocking_session_id, 
    r.wait_type, 
    r.wait_time, 
    r.wait_resource, 
    request_sql_text = st.text, 
    s.program_name, 
    most_recent_sql_text = stc.text 
from sys.dm_tran_locks l 
left join sys.dm_exec_requests r 
on l.request_session_id = r.session_id 
left join sys.dm_exec_sessions s 
on l.request_session_id = s.session_id 
left join sys.dm_exec_connections c 
on s.session_id = c.session_id 
outer apply sys.dm_exec_sql_text(r.sql_handle) st 
outer apply sys.dm_exec_sql_text(c.most_recent_sql_handle) stc 
where l.resource_database_id = db_id('NazwaBazyDanych') 
order by request_session_id; 

Wynik zapytania:

kill 62 
go

Zmiana bazy na single user mode / Multi user mode

 

Zapytanie uruchamiamy w SSMS z wybraną bazą master:

ALTER DATABASE NazwaBAZY 
SET SINGLE_USER; 
GO 

 

ALTER DATABASE NazwaBAZY 
SET MULTI_USER; 
GO 

Rebuild pliku LDF (plik logów bazy danych)

Przełączenie bazy w tryb Offline:

Jeśli zadanie trwa dłużej niż kilka sekund/minut należy ubić sesje ręcznie 

Sprawdzenie co blokuje... | Konio-DC Bookstack

Przebudowa logów:

Dobrą praktyką jest zapisane najpierw do nowego pliku, a następnie zmiana nazwy oryginalnego pliku na taką z dopiskiem "_OLD". Potem należy z powrotem przełączyć bazę w tryb online i znowu offline, a następnie ponownie wykonać przebudowę logów już z taką nazwą jaka była oryginalnie. 

alter database [NazwaBazy] rebuild log on(Name=[NazwaLogiczna_Pliku_LOG], Filename='Ścieżka_do_nowego pliku.ldf') 

 Przykładowy wynik:

Przywrócenie bazy w tryb Online: 

Jeśli obok nazwy bazy jest "(Restricted User)" to należy przełączyć bazę ma Multi User
Zmiana bazy na single ... | Konio-DC Bookstack

Przełączenie bazy z mode SIMPLE na FULL

ALTER DATABASE [NazwaBazy] SET RECOVERY FULL;

W przeciwny razie nie będzie wykonywać się backup logów

Weryfikacja:

SELECT name, log_reuse_wait_desc FROM sys.DATABASES 

Weryfikacja TotalIndexSize / Sprawdzenia potrzebnego miejsca na dysku dla reindexacji

Wykonujemy z poziomu SSMS z wybraną odpowiednią bazą

SELECT 
    SUM(p.used_page_count) * 8 / 1024.0 / 1024.0  AS TotalIndexSizeGB 
FROM 
    sys.dm_db_partition_stats p 
JOIN 
    sys.indexes i ON p.object_id = i.object_id AND p.index_id = i.index_id 
WHERE 
    i.type > 0;  -- Exclude heap indexes (index_id = 0) 
GO 


Weryfikacja statusu indeksacji bazy danych

Wykonujemy w SSMS z wybraną bazą master.

SELECT TOP (10000000) [ID] 
      ,[DatabaseName] 
      ,[SchemaName] 
      ,[ObjectName] 
      ,[ObjectType] 
      ,[IndexName] 
      ,[IndexType] 
      ,[StatisticsName] 
      ,[PartitionNumber] 
      ,[ExtendedInfo] 
      ,[Command] 
      ,[CommandType] 
      ,[StartTime] 
      ,[EndTime] 
      ,[ErrorNumber] 
      ,[ErrorMessage] 
  FROM [master].[dbo].[CommandLog] 
-- where [CommandType] = 'ALTER_INDEX'
  order by [StartTime] desc 

 

Sprawdzenie wersji edycji silnika MSSQL (Express / Standard / Enterprise)

Wykonujemy w SSMS z wybraną bazą master

SELECT 
    SERVERPROPERTY('Edition') AS 'Edition ', 
    SERVERPROPERTY('ProductVersion') AS 'Product Version ', 
    SERVERPROPERTY('ProductLevel') AS 'Product Level ', 
    SERVERPROPERTY('EngineEdition') AS 'Engine Edition ' 

 

Downgrade / zmiana edycji silnika MSSQL

Wykonujemy z poziomu CMD, w katalogu z plikami instalacyjnymi MSSQL

setup.exe /ACTION=EditionUpgrade /SkipRules=Cluster_EditionDownGradeCheck 

Sprawdzenie wielkości danych w msdb

Wykonujemy w SSMS z wybraną bazą danych msdb

USE msdb 
GO 

SELECT TOP(10) 
      o.[object_id] 
    , obj = SCHEMA_NAME(o.[schema_id]) + '.' + o.name 
    , o.[type] 
    , i.total_rows 
    , i.total_size 
FROM sys.objects o 
JOIN ( 
    SELECT 
          i.[object_id] 
        , total_size = CAST(SUM(a.total_pages) * 8. / 1024 AS DECIMAL(18,2)) 
        , total_rows = SUM(CASE WHEN i.index_id IN (0, 1) AND a.[type] = 1 THEN p.[rows] END) 
    FROM sys.indexes i 
    JOIN sys.partitions p ON i.[object_id] = p.[object_id] AND i.index_id = p.index_id 
    JOIN sys.allocation_units a ON p.[partition_id] = a.container_id 
    WHERE i.is_disabled = 0 
        AND i.is_hypothetical = 0 
    GROUP BY i.[object_id] 
) i ON o.[object_id] = i.[object_id] 
WHERE o.[type] IN ('V', 'U', 'S') 
ORDER BY i.total_size DESC 

 

Sprawdzenie zajętości plików bazy danych

Wykonujemy w SSMS z wybraną bazą danych master

DECLARE @DB NVARCHAR(128) = 'NazwaBazyDanych'; 
DECLARE @sql NVARCHAR(MAX); 

SET @sql = N' 
USE ' + QUOTENAME(@DB) + N'; 
SELECT 
    ''' + @DB + N''' AS DatabaseName, 
    mf.name AS LogicalFileName, 
    mf.physical_name AS PhysicalFileName, 
    mf.type_desc AS FileType, 
    mf.size / 128.0 AS FileSizeMB, 
    FILEPROPERTY(mf.name, ''SpaceUsed'') / 128.0 AS SpaceUsedMB, 
    (FILEPROPERTY(mf.name, ''SpaceUsed'') / 128.0) / (mf.size / 128.0) * 100 AS SpaceUsedPercent 
FROM 
    sys.master_files mf 
WHERE 
    mf.database_id = DB_ID(''' + @DB + N'''); '; 

-- Execute the dynamic SQL 
EXEC sp_executesql @sql; 

Sprawdzenie aktualnie działających jobów SQL Agent

Wykonujemy w SSMS z wybraną bazą master 

   WITH
    CTE_Sysession (AgentStartDate)
    AS
    (
        SELECT MAX(AGENT_START_DATE) AS AgentStartDate FROM MSDB.DBO.SYSSESSIONS
    )
SELECT sjob.name AS JobName 
        ,CASE  
            WHEN SJOB.enabled = 1 THEN 'Enabled' 
            WHEN sjob.enabled = 0 THEN 'Disabled' 
            END AS JobEnabled 
        ,sjob.description AS JobDescription 
        ,CASE  
            WHEN ACT.start_execution_date IS NOT NULL AND ACT.stop_execution_date IS NULL  THEN 'Running' 
            WHEN ACT.start_execution_date IS NOT NULL AND ACT.stop_execution_date IS NOT NULL AND HIST.run_status = 1 THEN 'Stopped' 
            WHEN HIST.run_status = 0 THEN 'Failed' 
            WHEN HIST.run_status = 3 THEN 'Canceled' 
        END AS JobActivity 
        ,DATEDIFF(MINUTE,act.start_execution_date, GETDATE()) DurationMin 
        ,hist.run_date AS JobRunDate 
        ,run_DURATION/10000 AS Hours 
        ,(run_DURATION%10000)/100 AS Minutes  
        ,(run_DURATION%10000)%100 AS Seconds 
        ,hist.run_time AS JobRunTime  
        ,hist.run_duration AS JobRunDuration 
        ,act.start_execution_date AS JobStartDate 
        ,act.last_executed_step_id AS JobLastExecutedStep 
        ,act.last_executed_step_date AS JobExecutedStepDate 
        ,act.stop_execution_date AS JobStopDate 
        ,act.next_scheduled_run_date AS JobNextRunDate 
        ,sjob.date_created AS JobCreated 
        ,sjob.date_modified AS JobModified       
            FROM MSDB.DBO.syssessions AS SYS1 
        INNER JOIN CTE_Sysession AS SYS2 ON SYS2.AgentStartDate = SYS1.agent_start_date 
        JOIN  msdb.dbo.sysjobactivity act ON act.session_id = SYS1.session_id 
        JOIN msdb.dbo.sysjobs sjob ON sjob.job_id = act.job_id 
        LEFT JOIN  msdb.dbo.sysjobhistory hist ON hist.job_id = act.job_id AND hist.instance_id = act.job_history_id 
        WHERE ACT.start_execution_date IS NOT NULL AND ACT.stop_execution_date IS NULL 
        ORDER BY ACT.start_execution_date DESC

 Przykładowy wynik:

image.png

Naprawa uprawnień usera SQL po odtworzeniu baz (zmiana ID)

Komendę uruchamiamy na bazie w której user powinien mieć naprawione uprawnienia bądź dodajemy:

USE [NazwaBazy]
EXEC sp_change_users_login 'Auto_Fix', 'NazwaUsera';

image.png

Wyciąganie pliku JPK w XML z baz Optimy

Uruchamiamy w PowerShell z konta które ma połączenie autentykacją windows do bazy danych:

$server = "NazwaSerwera"
$db     = "NazwaBazy"
$nazwa  = "NazwaPlikuDocelowego"
$out    = "C:\SciezkaDocelowa\$nazwa.xml"
$tabela = "[NazwaBazy].[NazwaTabeli]" #Zwykle [NazwaBazy].[CDN].[PlikiJPK]

$conn = New-Object System.Data.SqlClient.SqlConnection("Server=$server;Database=$db;Integrated Security=True")
$conn.Open()
$cmd = $conn.CreateCommand()
$cmd.CommandText = "SELECT JPK_XML FROM $tabela WHERE JPK_Nazwa = @n"
$null = $cmd.Parameters.AddWithValue("@n", $nazwa)
$bytes = [byte[]]$cmd.ExecuteScalar()
$conn.Close()

[IO.File]::WriteAllBytes($out, $bytes)
Write-Host "Zapisano $($bytes.Length) bajtów do $out"

image.png

Zbieranie danych:

Pobieranie danych o JPK by wiedzieć jak wygląda tabela:

SELECT TOP (10) [JPK_JPKID]
      ,[JPK_KodOsoby]
      ,[JPK_Typ]
      ,[JPK_Nazwa]
      ,[JPK_DataUtworzenia]
      ,[JPK_CelZlozenia]
      ,[JPK_WariantFormularza]
      ,[JPK_XML]
      ,[JPK_RefNr]
      ,[JPK_Path]
      ,[JPK_Status]
      ,[JPK_StatusCode]
      ,[JPK_StatusOpis]
      ,[JPK_KodUrzedu]
      ,[JPK_DataWyslania]
      ,[JPK_DataWplyniecia]
      ,[JPK_KodOsobyOdbierajacej]
      ,[JPK_DataOdebrania]
      ,[JPK_SkrotDokumentu]
      ,[JPK_SkrotStruktury]
      ,[JPK_StrukturaLogiczna]
      ,[JPK_StempelCzasu]
      ,[JPK_SigningTime]
      ,[JPK_NazwaPodmiotu]
      ,[JPK_NIP1]
      ,[JPK_OkresOd]
      ,[JPK_OkresDo]
  FROM [NazwaBazy].[CDN].[PlikiJPK] 

image.png

Weryfikacja w SSMS które kolumny są varbinary (zawierają pliki)

SELECT t.TABLE_NAME, c.COLUMN_NAME, c.DATA_TYPE
FROM INFORMATION_SCHEMA.COLUMNS c
JOIN INFORMATION_SCHEMA.TABLES t ON t.TABLE_NAME = c.TABLE_NAME
WHERE c.DATA_TYPE IN ('varbinary','image','xml')
  AND (t.TABLE_NAME LIKE '%JPK%' OR c.COLUMN_NAME LIKE '%JPK%');

image.png

Wciągnięcie modyfikacji danych w księgach rozliczeniowych - OPTIMA

DECLARE @Od    date = '2026-01-01';   -- okno akcji: początek roku
DECLARE @Do    date = '2026-07-08';   -- koniec półotwarty = do 7 lipca włącznie
DECLARE @StareOd date = '2025-01-01'; -- "stare księgi": rok 2025
DECLARE @StareDo date = '2026-01-01';

IF OBJECT_ID('tempdb..#baza') IS NOT NULL DROP TABLE #baza;

SELECT
    n.DeN_DeNId,
    n.DeN_Dziennik,
    n.DeN_NrDziennika,
    n.DeN_DataDok,
    n.DeN_Bufor,
    n.DeN_TS_Zal,
    n.DeN_TS_Mod,
    CASE WHEN n.DeN_TS_Zal >= @Od AND n.DeN_TS_Zal < @Do
         THEN 'Nowy wpis z datą 2025'
         ELSE 'Modyfikacja starego wpisu' END AS TypZmiany,
    CASE WHEN n.DeN_TS_Zal >= @Od AND n.DeN_TS_Zal < @Do
         THEN n.DeN_TS_Zal ELSE n.DeN_TS_Mod END AS AkcjaTS
INTO #baza
FROM CDN.DekretyNag n
WHERE n.DeN_DataDok >= @StareOd AND n.DeN_DataDok < @StareDo        -- księga 2025
  AND ( (n.DeN_TS_Zal >= @Od AND n.DeN_TS_Zal < @Do)
     OR (n.DeN_TS_Mod >= @Od AND n.DeN_TS_Mod < @Do) );             -- ruszone w 2026

-- 1) LISTA SZCZEGÓŁOWA
SELECT
    b.DeN_Dziennik,
    b.DeN_NrDziennika,
    b.DeN_DataDok  AS DataKsieg_2025,
    b.AkcjaTS      AS KiedyRuszone_2026,
    b.TypZmiany,
    b.DeN_Bufor,
    e.DeE_KontoWn,
    e.DeE_KontoMa,
    e.DeE_Kwota,
    e.DeE_Kategoria,
    e.DeE_Dokument
FROM #baza b
JOIN CDN.DekretyElem e ON e.DeE_DeNId = b.DeN_DeNId
ORDER BY b.AkcjaTS, b.DeN_Dziennik, b.DeN_NrDziennika, e.DeE_Lp;

-- 2) PODSUMOWANIE: ile dokumentów dot. 2025 ruszono w kolejnych miesiącach 2026
SELECT
    DATEFROMPARTS(YEAR(b.AkcjaTS), MONTH(b.AkcjaTS), 1) AS MiesiacAkcji,
    b.TypZmiany,
    COUNT(*)                                            AS LiczbaDokumentow,
    SUM(CASE WHEN b.DeN_Bufor = 1 THEN 1 ELSE 0 END)    AS WBuforze
FROM #baza b
GROUP BY DATEFROMPARTS(YEAR(b.AkcjaTS), MONTH(b.AkcjaTS), 1), b.TypZmiany
ORDER BY MiesiacAkcji, TypZmiany;

DROP TABLE #baza;

Wynik:

image.png