Wednesday, April 29, 2020

Memory Grants Pending value

 Memory Grants Pending value

Here's a SQL query you can use to check for **pending memory grants** on your SQL Server instance. This can be a useful indicator of memory pressure, as it shows how many requests are waiting for memory to be allocated.

SELECT @@SERVERNAME AS [Server Name]
 ,RTRIM([object_name]) AS [Object Name]
 ,cntr_value AS [Memory Grants Pending]
FROM sys.dm_os_performance_counters WITH (NOLOCK)
WHERE [object_name] LIKE N'%Memory Manager%' -- Handles named instances
 AND counter_name = N'Memory Grants Pending'
OPTION (RECOMPILE);

For more in-depth information about the `sys.dm_os_performance_counters` dynamic management view, you can refer to the official Microsoft documentation: dm_os_performance_counters

If you're interested in further exploring SQL Server memory management, here are some related posts that might be helpful:

Find a current blocking connection

 Find a current blocking connection

Here's a handy SQL query to help you identify and troubleshoot blocking in your SQL Server environment. This script combines information from several dynamic management views (DMVs) to give you a clear picture of what's waiting, what's blocking it, and the SQL statements involved.

SELECT t1.resource_type AS [Lock Type],
  DB_NAME(resource_database_id) AS [Database],
  t1.resource_associated_entity_id AS [Blocking Object],
  t1.request_mode AS [Lock Request], -- The lock being requested
  t1.request_session_id AS [Waiter SPID],
  t2.wait_duration_ms AS [Wait Time], -- How long the session has been waiting
  (
    SELECT [text]
    FROM sys.dm_exec_requests AS r WITH (NOLOCK) -- Get the SQL for the waiting session's batch
    CROSS APPLY sys.dm_exec_sql_text(r.[sql_handle])
    WHERE r.session_id = t1.request_session_id
  ) AS [Waiter Batch],
  (
    SELECT SUBSTRING(qt.[text], r.statement_start_offset / 2, (
      CASE
        WHEN r.statement_end_offset = - 1
        THEN LEN(CONVERT(NVARCHAR(max), qt.[text])) * 2
        ELSE r.statement_end_offset
      END - r.statement_start_offset
    ) / 2)
    FROM sys.dm_exec_requests AS r WITH (NOLOCK)
    CROSS APPLY sys.dm_exec_sql_text(r.[sql_handle]) AS qt
    WHERE r.session_id = t1.request_session_id
  ) AS [Waiter Statement], -- The specific statement being blocked
  t2.blocking_session_id AS [Blocker SPID], -- The SPID of the session causing the block
  (
    SELECT [text]
    FROM sys.sysprocesses AS p -- Get the SQL for the blocking session's batch
    CROSS APPLY sys.dm_exec_sql_text(p.[sql_handle])
    WHERE p.spid = t2.blocking_session_id
  ) AS [Blocker Batch]
FROM sys.dm_tran_locks AS t1 WITH (NOLOCK)
INNER JOIN sys.dm_os_waiting_tasks AS t2 WITH (NOLOCK) ON t1.lock_owner_address = t2.resource_address
OPTION (RECOMPILE);

This query joins sys.dm_tran_locks (information about current lock requests) with sys.dm_os_waiting_tasks (information about tasks that are waiting on something) to link waiting sessions to their blockers. It then uses sys.dm_exec_requests and sys.sysprocesses to retrieve the actual SQL text for both the waiting and blocking sessions, helping you pinpoint the exact statements causing issues.

For more detailed information on the DMVs used in this query, you can refer to the official Microsoft documentation:

Wednesday, April 22, 2020

SQL Server Permission

 

Query to List SQL Server Logins with Their Server-Level Roles

In SQL Server, it’s often necessary to audit or review logins and determine what server-level roles are assigned to each. The following query retrieves a list of all SQL Server logins, along with flags indicating whether each login is a member of a particular server role (such as sysadmin, securityadmin, serveradmin, etc.).

This script uses a Common Table Expression (CTE) to pivot role membership data into columns, making it easy to view role assignments at a glance.

SQL Query

WITH cte_srm AS (
  SELECT
    srm.member_principal_id,
    MAX(CASE WHEN srm.role_principal_id = 3 THEN 1 END) AS sysadmin,
    MAX(CASE WHEN srm.role_principal_id = 4 THEN 1 END) AS securityadmin,
    MAX(CASE WHEN srm.role_principal_id = 5 THEN 1 END) AS serveradmin,
    MAX(CASE WHEN srm.role_principal_id = 6 THEN 1 END) AS setupadmin,
    MAX(CASE WHEN srm.role_principal_id = 7 THEN 1 END) AS processadmin,
    MAX(CASE WHEN srm.role_principal_id = 8 THEN 1 END) AS diskadmin,
    MAX(CASE WHEN srm.role_principal_id = 9 THEN 1 END) AS dbcreator,
    MAX(CASE WHEN srm.role_principal_id = 10 THEN 1 END) AS bulkadmin
  FROM sys.server_principals AS sp
  JOIN sys.server_role_members AS srm 
    ON sp.principal_id = srm.role_principal_id
  WHERE sp.[type] = 'R'
  GROUP BY srm.member_principal_id
)

SELECT
  pr.[sid],
  CAST(NULL AS SMALLINT) AS [status],
  pr.create_date,
  pr.modify_date AS updatedate,
  pr.create_date AS accdate,
  0 AS totcpu,
  0 AS totio,
  0 AS spacelimit,
  0 AS timelimit,
  0 AS resultlimit,
  pr.[name],
  pr.default_database_name AS dbname,
  CAST(NULL AS SYSNAME) AS [password],
  pr.default_language_name AS [language],
  CAST(CASE WHEN pe.state = 'D' THEN 1 ELSE 0 END AS INT) AS denylogin,
  CAST(CASE WHEN pe.state = 'G' THEN 1 ELSE 0 END AS INT) AS hasaccess,
  CAST(CASE WHEN pr.[type] IN ('U', 'G') THEN 1 ELSE 0 END AS INT) AS isntname,
  CAST(CASE WHEN pr.[type] = 'G' THEN 1 ELSE 0 END AS INT) AS isntgroup,
  CAST(CASE WHEN pr.[type] = 'U' THEN 1 ELSE 0 END AS INT) AS isntuser,
  ISNULL(cte_srm.sysadmin, 0) AS sysadmin,
  ISNULL(cte_srm.securityadmin, 0) AS securityadmin,
  ISNULL(cte_srm.serveradmin, 0) AS serveradmin,
  ISNULL(cte_srm.setupadmin, 0) AS setupadmin,
  ISNULL(cte_srm.processadmin, 0) AS processadmin,
  ISNULL(cte_srm.diskadmin, 0) AS diskadmin,
  ISNULL(cte_srm.dbcreator, 0) AS dbcreator,
  ISNULL(cte_srm.bulkadmin, 0) AS bulkadmin,
  pr.[name] AS loginname
FROM sys.server_principals AS pr
LEFT OUTER JOIN sys.server_permissions AS pe 
  ON pr.principal_id = pe.grantee_principal_id AND pe.[type] = 'COSQ'
LEFT OUTER JOIN cte_srm 
  ON pr.principal_id = cte_srm.member_principal_id
WHERE pr.[type] <> 'R';
GO

Summary

This query provides a comprehensive overview of each SQL Server login, including:

  • Login metadata (creation date, default database, language)
  • Access status (denied login, granted access)
  • Role membership (server-level roles shown as 0 or 1)

You can use or adapt this script for server audits, role reviews, or security assessments.

Sunday, April 12, 2020

Database levels modeling


Database levels Modeling


There are three levels of data modeling: conceptual data model, logical data model, and physical data model.

Feature Conceptual Logical Physical
Entity Names ? ?  
Entity Relationships ? ?  
Attributes / Column   ?  
Primary Keys   ? ?
Foreign Keys   ? ?
Table Names     ?
Column Names     ?
Column Data Types     ?

Conceptual Data Model

Database modeling levels

'Conceptual schema' is a high-level design of business information. It typically includes only the main concepts and the main relationships among them.

Logical Data Model

Logical Data Model

Contains logical information, data, and groups.

Physical Data Model

Contains everything required to create databases and tables, such as column names and data types.

https://www.guru99.com/data-modelling-conceptual-logical.html

Kill all user processes for a database

 

Safely Terminating Connections in SQL Server (For Test/Dev Use Only)

When working in development or testing environments, you might find it necessary to forcibly disconnect all active sessions from a particular database — for example, before running maintenance tasks or restoring a backup. However, use this procedure with caution and never run it in production environments unless you're absolutely sure of the consequences.

T-SQL Stored Procedure to Kill All Active Sessions on a Database

Below is a T-SQL script that finds and terminates all active connections to a specific database, excluding your own session. This script uses a cursor to loop through the session IDs (SPID) connected to the target database and executes the KILL command for each.

DECLARE @spid INT;
DECLARE @sqlString NVARCHAR(100);

DECLARE conn_cursor CURSOR FOR
    SELECT [SPID] 
    FROM [master].[dbo].sysprocesses
    WHERE [DbId] = DB_ID('DBName') AND [SPID] <> @SPID;

OPEN conn_cursor;
FETCH NEXT FROM conn_cursor INTO @spid;

WHILE @FETCH_STATUS = 0
BEGIN
    SET @sqlString = 'KILL ' + CAST(@spid AS NVARCHAR(10));
    PRINT @sqlString;
    EXECUTE sp_executesql @sqlString;
    FETCH NEXT FROM conn_cursor INTO @spid;
END;

CLOSE conn_cursor;
DEALLOCATE conn_cursor;

Notes

  • Replace 'DBName' with the name of your target database.
  • This approach uses the legacy sysprocesses system table, which is still available but deprecated. For newer SQL Server versions, consider using the sys.dm_exec_sessions or sys.dm_exec_requests views for more modern alternatives.
  • Always make sure you're targeting the correct environment to avoid unintentional disruptions.

I/O Statistics by file for the current database

 Understanding SQL Server File I/O Performance with `dm_io_virtual_file_stats`

If you're managing a SQL Server database, keeping an eye on file input/output (I/O) performance is crucial for maintaining optimal speed and responsiveness. The `sys.dm_io_virtual_file_stats` dynamic management view (DMV) is an incredibly powerful tool for gaining deep insights into how your database files are behaving. It provides detailed metrics on reads, writes, I/O stalls, and more, allowing you to pinpoint potential bottlenecks.

Combined with `sys.database_files`, this DMV gives you a comprehensive overview of your database's physical and logical file performance. Below is a useful SQL query that leverages these views to present a clear picture of your database's I/O activity:

SELECT DB_NAME(DB_ID()) AS [Database Name]
 ,df.name AS [Logical Name]
 ,vfs.[file_id]
 ,df.type_desc
 ,df.physical_name AS [Physical Name]
 ,CAST(vfs.size_on_disk_bytes / 1048576.0 AS DECIMAL(10, 2)) AS [Size on Disk (MB)]
 ,vfs.num_of_reads
 ,vfs.num_of_writes
 ,vfs.io_stall_read_ms
 ,vfs.io_stall_write_ms
 ,CAST(100. * vfs.io_stall_read_ms / (vfs.io_stall_read_ms + vfs.io_stall_write_ms) AS DECIMAL(10, 1)) AS [IO Stall Reads Pct]
 ,CAST(100. * vfs.io_stall_write_ms / (vfs.io_stall_write_ms + vfs.io_stall_read_ms) AS DECIMAL(10, 1)) AS [IO Stall Writes Pct]
 ,(vfs.num_of_reads + vfs.num_of_writes) AS [Writes + Reads]
 ,CAST(vfs.num_of_bytes_read / 1048576.0 AS DECIMAL(10, 2)) AS [MB Read]
 ,CAST(vfs.num_of_bytes_written / 1048576.0 AS DECIMAL(10, 2)) AS [MB Written]
 ,CAST(100. * vfs.num_of_reads / (vfs.num_of_reads + vfs.num_of_writes) AS DECIMAL(10, 1)) AS [# Reads Pct]
 ,CAST(100. * vfs.num_of_writes / (vfs.num_of_reads + vfs.num_of_writes) AS DECIMAL(10, 1)) AS [# Write Pct]
 ,CAST(100. * vfs.num_of_bytes_read / (vfs.num_of_bytes_read + vfs.num_of_bytes_written) AS DECIMAL(10, 1)) AS [Read Bytes Pct]
 ,CAST(100. * vfs.num_of_bytes_written / (vfs.num_of_bytes_read + vfs.num_of_bytes_written) AS DECIMAL(10, 1)) AS [Written Bytes Pct]
FROM sys.dm_io_virtual_file_stats(DB_ID(), NULL) AS vfs
INNER JOIN sys.database_files AS df WITH (NOLOCK) ON vfs.[file_id] = df.[file_id]
OPTION (RECOMPILE);
  

Key Metrics Explained:

  • Size on Disk (MB): The current size of the database file.
  • num_of_reads / num_of_writes: Total number of reads/writes since the last SQL Server restart or database online event.
  • io_stall_read_ms / io_stall_write_ms: The total time, in milliseconds, that users waited for reads/writes to complete. High values here can indicate I/O bottlenecks.
  • IO Stall Reads Pct / IO Stall Writes Pct: Percentage of I/O stall time attributed to reads or writes.
  • MB Read / MB Written: Total megabytes read from or written to the file.
  • # Reads Pct / # Write Pct: Percentage of total I/O operations (reads + writes) that are reads or writes.
  • Read Bytes Pct / Written Bytes Pct: Percentage of total I/O bytes transferred that are reads or writes.

For more detailed information on these system views, you can refer to the official Microsoft documentation:

By regularly monitoring these metrics, you can proactively identify and address I/O performance issues, ensuring your SQL Server databases run smoothly and efficiently.

How to access remote server database tables

Working with Ad Hoc Distributed Queries in SQL Server

By default, SQL Server restricts the use of ad hoc distributed queries with functions like OPENROWSET and OPENDATASOURCE. This behavior enhances security by requiring administrators to explicitly enable these options before allowing access to external data sources.

To enable ad hoc queries, run the following commands:

-- Enable advanced options
sp_configure 'show advanced options', 1;
RECONFIGURE;
GO

-- Enable Ad Hoc Distributed Queries
sp_configure 'Ad Hoc Distributed Queries', 1;
RECONFIGURE;
GO

Once enabled, you can query remote data sources without creating a linked server. For example:

SELECT TOP 10 *
FROM OPENDATASOURCE('MSOLEDBSQL',
  'Server=myserver;Database=mydatabase;TrustServerCertificate=Yes;Trusted_Connection=Yes;').mydatabase.dbo.TableA;

🔗 Microsoft Docs: Ad Hoc Distributed Queries


Using OPENROWSET

The OPENROWSET function lets you access remote data using OLE DB in a one-time, ad hoc manner. It includes connection details and the query to execute against the remote source. While useful for occasional access, it's recommended to use linked servers for repeated queries.

Example:

SELECT a.*
FROM OPENROWSET('SQLNCLI', 
    'Server=DEO-myserver;Trusted_Connection=yes;', 
    'SELECT TOP 10 * FROM DbName.dbo.TableA') AS a;

🔗 Microsoft Docs: OPENROWSET


Using OPENQUERY

OPENQUERY allows you to execute a pass-through query on a linked server. The query runs directly on the remote server and can be used in SELECT, INSERT, UPDATE, or DELETE statements.

Examples:

-- Insert data
INSERT OPENQUERY(OracleSvr, 'SELECT name FROM joe.titles')  
VALUES ('NewTitle');

-- Update data
UPDATE OPENQUERY(OracleSvr, 'SELECT name FROM joe.titles WHERE id = 101')  
SET name = 'ADifferentName';

-- Delete data
DELETE OPENQUERY(OracleSvr, 'SELECT name FROM joe.titles WHERE name = ''NewTitle''');

-- Query data
SELECT * FROM OPENQUERY(OracleSvr, 'SELECT name FROM joe.titles WHERE name = ''NewTitle''');

🔗 Microsoft Docs: OPENQUERY


Using OPENDATASOURCE

OPENDATASOURCE offers a way to define connection details inline in your query without setting up a linked server. It supports four-part naming to reference remote objects.

Examples:

-- Access a SQL Server instance
SELECT *  
FROM OPENDATASOURCE('SQLNCLI',  
    'Data Source=London\\Payroll;Integrated Security=SSPI').AdventureWorks2012.HumanResources.Employee;

-- Read from an Excel file
SELECT * 
FROM OPENDATASOURCE('Microsoft.Jet.OLEDB.4.0',  
 'Data Source=C:\\DataFolder\\Documents\\TestExcel.xls;Extended Properties=EXCEL 5.0')...[Sheet1$];

-- Query data from another SQL Server
SELECT GroupName, Name, DepartmentID  
FROM OPENDATASOURCE('MSOLEDBSQL', 
  'Server=Seattle1;Database=AdventureWorks2016;TrustServerCertificate=Yes;Trusted_Connection=Yes;').HumanResources.Department  
ORDER BY GroupName, Name;

🔗 Microsoft Docs: OPENDATASOURCE
🔗 Importing Bulk Data with OPENROWSET and BULK INSERT


This article outlines how to use SQL Server’s ad hoc query features to interact with external data sources efficiently. These tools are especially useful for data migration, one-time imports, or interacting with legacy systems without altering your current environment.

How to find SQL Server database job step info using T-SQL

 

Exploring SQL Server Agent Job Metadata in MSDB

SQL Server Agent manages scheduled tasks, often referred to as jobs. Understanding how these jobs are structured and executed involves querying several system tables in the msdb database. Below, we provide a breakdown of key tables and a useful query to explore job step metadata.

Key System Tables in MSDB

1. dbo.sysjobs

This table stores metadata about each SQL Server Agent job, such as the job ID, name, and owner. Every scheduled task configured in SQL Server Agent is recorded here.

2. dbo.sysjobsteps

Each job can contain multiple steps, and this table holds detailed information about every step within each job, including the type of operation it performs, the command it executes, and its success or failure behavior.

3. dbo.sysproxies

This table defines SQL Server Agent proxy accounts. Proxy accounts allow specific job steps to run under different security contexts, which is useful for accessing external resources securely.


Query: Retrieve Detailed Job Step Information

The following SQL query provides a detailed breakdown of each step within a specific job. It shows the job and step IDs, step names, execution type, associated proxy account, command being executed, and the configured actions on success or failure.


-->> Job Step Details
SELECT 
    sJOB.job_id AS JobID,
    sJOB.name AS JobName,
    sJSTP.step_uid AS StepID,
    sJSTP.step_id AS StepNo,
    sJSTP.step_name AS StepName,
    CASE sJSTP.subsystem
        WHEN 'ActiveScripting' THEN 'ActiveX Script'
        WHEN 'CmdExec' THEN 'Operating system (CmdExec)'
        WHEN 'PowerShell' THEN 'PowerShell'
        WHEN 'Distribution' THEN 'Replication Distributor'
        WHEN 'Merge' THEN 'Replication Merge'
        WHEN 'QueueReader' THEN 'Replication Queue Reader'
        WHEN 'Snapshot' THEN 'Replication Snapshot'
        WHEN 'LogReader' THEN 'Replication Transaction-Log Reader'
        WHEN 'ANALYSISCOMMAND' THEN 'SQL Server Analysis Services Command'
        WHEN 'ANALYSISQUERY' THEN 'SQL Server Analysis Services Query'
        WHEN 'SSIS' THEN 'SQL Server Integration Services Package'
        WHEN 'TSQL' THEN 'Transact-SQL script (T-SQL)'
        ELSE sJSTP.subsystem
    END AS StepType,
    sPROX.name AS RunAs,
    sJSTP.database_name AS Database,
    sJSTP.command AS ExecutableCommand,
    CASE sJSTP.on_success_action
        WHEN 1 THEN 'Quit the job reporting success'
        WHEN 2 THEN 'Quit the job reporting failure'
        WHEN 3 THEN 'Go to the next step'
        WHEN 4 THEN 'Go to Step: ' + QUOTENAME(CAST(sJSTP.on_success_step_id AS VARCHAR(3))) + ' ' + sOSSTP.step_name
    END AS OnSuccessAction,
    sJSTP.retry_attempts AS RetryAttempts,
    sJSTP.retry_interval AS [RetryInterval (Minutes)],
    CASE sJSTP.on_fail_action
        WHEN 1 THEN 'Quit the job reporting success'
        WHEN 2 THEN 'Quit the job reporting failure'
        WHEN 3 THEN 'Go to the next step'
        WHEN 4 THEN 'Go to Step: ' + QUOTENAME(CAST(sJSTP.on_fail_step_id AS VARCHAR(3))) + ' ' + sOFSTP.step_name
    END AS OnFailureAction
FROM msdb.dbo.sysjobsteps AS sJSTP
INNER JOIN msdb.dbo.sysjobs AS sJOB
    ON sJSTP.job_id = sJOB.job_id
LEFT JOIN msdb.dbo.sysjobsteps AS sOSSTP
    ON sJSTP.job_id = sOSSTP.job_id AND sJSTP.on_success_step_id = sOSSTP.step_id
LEFT JOIN msdb.dbo.sysjobsteps AS sOFSTP
    ON sJSTP.job_id = sOFSTP.job_id AND sJSTP.on_fail_step_id = sOFSTP.step_id
LEFT JOIN msdb.dbo.sysproxies AS sPROX
    ON sJSTP.proxy_id = sPROX.proxy_id
WHERE sJOB.name = 'your database name'
ORDER BY JobName, StepNo;

When to Use This Query

This script is especially helpful when auditing jobs, troubleshooting execution flows, or reviewing complex step logic. The classification of StepType, RunAs, and success/failure actions allows for a detailed understanding of how SQL Server Agent is configured to execute tasks.


References

How to find SQL Server job fail from history

 

Tracking SQL Server Agent Job Failures with dbo.sysjobhistory

The dbo.sysjobhistory system table, located in the msdb database, stores historical details about the execution of SQL Server Agent jobs. This table is essential for administrators who need to review past job executions, especially for identifying and troubleshooting failures.

Query: Retrieve Failed Job Steps

The SQL query below extracts information about failed SQL Server Agent job steps. It includes job names, step details, severity, failure messages, run dates and times, and the execution status.


-->> Job and Step Failure Details
SELECT
    j.name AS job_name,
    js.step_name,
    jh.sql_severity,
    jh.message,
    jh.run_date,
    jh.run_time,
    MSDB.dbo.agent_datetime(jh.run_date, jh.run_time) AS date_time,
    CASE jh.run_status
        WHEN 0 THEN 'Failed'
        WHEN 1 THEN 'Succeeded'
        WHEN 2 THEN 'Retry'
        WHEN 3 THEN 'Canceled'
        WHEN 4 THEN 'In progress'
    END AS run_status
FROM
    msdb.dbo.sysjobs AS j
INNER JOIN
    msdb.dbo.sysjobsteps AS js ON js.job_id = j.job_id
INNER JOIN
    msdb.dbo.sysjobhistory AS jh ON jh.job_id = j.job_id AND jh.step_id = js.step_id
WHERE
    jh.run_status = 0
    AND CAST(jh.run_date AS INT) > 20200318;

This query is especially useful for identifying job step failures after a specific date (20200318 in this example). The agent_datetime function is used to convert the run date and time into a more readable datetime format.

Tip: About agent_datetime

The agent_datetime function is a built-in MSDB utility that combines the run_date and run_time columns into a standard DATETIME value, making it easier to interpret scheduling data.

Additional Resources

How to find SQL Server procedure statistics.

 

Monitoring Cached Stored Procedure Performance in SQL Server

SQL Server provides a dynamic management view called sys.dm_exec_procedure_stats that helps you analyze the performance of cached stored procedures. This view returns one row for each stored procedure currently held in the plan cache. Once a procedure is removed from the cache, its corresponding row is also removed from the view.

Accessing this information requires the VIEW SERVER STATE permission on the SQL Server instance.

Sample Query: Analyze Cached Procedure Statistics

The following SQL query retrieves performance metrics for each cached stored procedure. It includes information such as the procedure name, database name, cache time, execution count, and average execution duration.


-- Procedure Performance Statistics
SELECT 
    d.object_id, 
    d.database_id, 
    OBJECT_NAME(object_id, database_id) AS [proc name],   
    DB_NAME(database_id) AS dbname,
    d.cached_time, 
    d.last_execution_time, 
    d.total_elapsed_time,  
    d.total_elapsed_time / d.execution_count AS [avg_elapsed_time],  
    d.last_elapsed_time, 
    d.execution_count  
FROM 
    sys.dm_exec_procedure_stats AS d  
ORDER BY 
    [total_worker_time] DESC;

This query is particularly useful for identifying procedures with high resource consumption or long execution times, helping DBAs optimize performance by focusing on the most impactful routines.

Further Reading

How to find Cross-database dependency

 

How to Find Database Dependencies in SQL Server Using

sql_expression_dependencies

In SQL Server, identifying dependencies between databases or database objects is essential for understanding the impact of changes and for troubleshooting. One of the key system catalog views for discovering such dependencies is sys.sql_expression_dependencies.


Basic Query to Find Database Object Dependencies

You can use the following query to list dependencies within the current database. This query returns the referencing database and object, the referenced schema and entity, the type of referenced object, and the referenced database name:


SELECT 
    DB_NAME() AS referencing_database_name,
    OBJECT_NAME(referencing_id) AS referencing_entity_name,
    ISNULL(referenced_schema_name, 'dbo') AS referenced_schema_name,
    referenced_entity_name,
    ao.type_desc AS referenced_entity_type,
    ISNULL(referenced_database_name, DB_NAME()) AS referenced_database_name
FROM sys.sql_expression_dependencies sed
JOIN sys.all_objects ao ON sed.referenced_entity_name = ao.name;


Finding Nested Level Dependencies

To track nested or recursive dependencies — for example, to see all objects that depend on a specific object through multiple levels — you can use a recursive common table expression (CTE). Here’s an example that starts from a specific object named 'obj-1':


WITH NestDep AS (
    SELECT 
        o.object_id AS referenced_id,
        o.name AS referenced_name,
        o.object_id AS referencing_id,
        o.name AS referencing_name,
        0 AS NestLvl
    FROM sys.objects o
    WHERE o.name = 'obj-1'

    UNION ALL

    SELECT
        d1.referenced_id,
        OBJECT_NAME(d1.referenced_id),
        d1.referencing_id,
        OBJECT_NAME(d1.referencing_id),
        NestLvl + 1
    FROM sys.sql_expression_dependencies d1
    JOIN NestDep r ON d1.referenced_id = r.referencing_id
)
SELECT DISTINCT 
    referenced_id,
    referenced_name,
    referencing_id,
    referencing_name,
    NestLvl
FROM NestDep
WHERE NestLvl > 0
ORDER BY NestLvl, referencing_id;

This query helps you visualize dependency chains across multiple levels.


Detecting Linked Server Dependencies

If your SQL Server environment uses linked servers, dependencies may span across servers. To identify such cross-server dependencies, you can run this query that filters for objects referencing external servers:


SELECT 
    DB_NAME() AS referencing_database_name,
    OBJECT_NAME(referencing_id) AS referencing_entity_name,
    ISNULL(referenced_schema_name, 'dbo') AS referenced_schema_name,
    referenced_entity_name,
    ao.type_desc AS referenced_entity_type,
    ISNULL(referenced_database_name, DB_NAME()) AS referenced_database_name,
    referenced_server_name
FROM sys.sql_expression_dependencies sed
JOIN sys.all_objects ao ON sed.referenced_entity_name = ao.name
WHERE referenced_server_name IS NOT NULL;


Useful Reference

For more detailed information on sys.sql_expression_dependencies, visit the official Microsoft documentation:

sys.sql_expression_dependencies (Transact-SQL)

How to work with a collation

 

Understanding Collations in SQL Server

Collations in SQL Server define the rules for sorting and comparing character data. They control properties such as case sensitivity and accent sensitivity for your data. When dealing with character data types like char and varchar, collations determine the code page and which characters can be stored.


Key Collation Options Explained

In collation names, you may encounter several common abbreviations:

  • CS – Case-Sensitive
  • AI – Accent-Insensitive
  • KS – Kana Type-Sensitive (for Japanese kana characters)
  • WS – Width-Sensitive (distinguishes between single-byte and double-byte characters)
  • SC – Supports Supplementary Characters
  • UTF8 – Uses UTF-8 Encoding Standard

Collation Levels in SQL Server

Collations can be set at different levels within a SQL Server instance, including:

  • Server-level collations
  • Database-level collations
  • Column-level collations
  • Expression-level collations

Server-Level Collations

The default collation for the SQL Server instance is chosen during installation. This setting applies to system databases as well as any new user databases created afterwards.

To check the current server collation, you can use the following query:

SELECT CONVERT(varchar, SERVERPROPERTY('collation'));
-- To find the code page of a specific collation
SELECT COLLATIONPROPERTY('Traditional_Spanish_CS_AS_KS_WS', 'CodePage');

To view all available collations supported by the server:

SELECT * FROM sys.fn_helpcollations();

Database-Level Collations

You can change the collation of a user database using the ALTER DATABASE command. For example:

ALTER DATABASE myDataBase COLLATE Latin1_General_CS_AI;

To check the collation of a particular database:

SELECT CONVERT(VARCHAR(50), DATABASEPROPERTYEX('database_name', 'collation'));

Or, to list collations for all databases:

SELECT name, collation_name FROM sys.databases;

Column-Level Collations

Collations can be assigned to individual columns within a table. To change the collation for a specific column:

ALTER TABLE myTable ALTER COLUMN mycol NVARCHAR(10) COLLATE Latin1_General_CS_AI;

Expression-Level Collations

Collations can also be applied at the expression level in queries to affect sorting and comparison results. This is useful when you want to enforce locale-specific sorting, for example with ORDER BY:

SELECT name FROM customer ORDER BY name COLLATE Latin1_General_CS_AI;

-- Or to join tables with different collations
SELECT * FROM TABLE1
INNER JOIN TABLE2 ON TABLE1.Col1 COLLATE Latin1_General_CS_AS = TABLE2.Col1 COLLATE Latin1_General_CS_AS;

Finding Collation for a Specific Column

To determine the collation used by a particular column, you can use this query:

SELECT OBJECT_NAME(OBJECT_ID), name AS ColumnName, collation_name AS ColumnCollation
FROM sys.columns
WHERE collation_name IS NOT NULL
AND OBJECT_NAME(OBJECT_ID) = '?'
AND name = '?';

Or to check all columns with collations across all databases:

EXEC dbo.sp_MSforeachdb N'SELECT TABLE_NAME, COLUMN_NAME, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH, COLLATION_NAME FROM ?.INFORMATION_SCHEMA.COLUMNS WHERE COLLATION_NAME IS NOT NULL;';

Useful References

Saturday, April 11, 2020

Get database scoped configuration values for the current database

 Get database scoped configuration values for the current database

Ever wondered how to check out the configurations specific to your SQL Server database? There's a handy system catalog view called sys.database_scoped_configurations that provides just what you need. This view lets you inspect various settings that are applied at the database level, giving you insights into how your database is configured.

For example, you can use the following SQL query to retrieve essential configuration details:

SELECT configuration_id
 ,name
 ,[value] AS [value_for_primary]
 ,value_for_secondary
FROM sys.database_scoped_configurations WITH (NOLOCK)
OPTION (RECOMPILE);

This query will show you the configuration ID, its name, the primary value (value_for_primary), and if applicable, a secondary value (value_for_secondary). It's a quick way to get a snapshot of these important settings.

Want to dive deeper into what this view offers? You can find more comprehensive documentation on Microsoft's official site: sys.database_scoped_configurations (Transact-SQL).

Monday, April 6, 2020

How to find /change SPN configuration

 

Understanding Service Principal Names (SPNs) in SQL Server

A Service Principal Name (SPN) is a unique identifier assigned to a specific service instance. SPNs play a crucial role in Kerberos authentication by linking a service instance to a service logon account. This mechanism enables client applications to request authentication from the service even if the client does not directly know the service account name.

When multiple instances of a service are installed across different computers in a network (forest), each instance must have its own unique SPN. Additionally, a single service instance can have multiple SPNs if clients may connect using different names or aliases. For instance, since an SPN always includes the host computer's name where the service runs, it’s possible for one service instance to register SPNs for all host names or aliases associated with that machine.

For more detailed information on SPN formats and how to create unique SPNs, refer to Microsoft’s documentation:
Service Principal Names


SPN Formats for SQL Server Instances

  • Named Instance SPN Format:

    MSSQLSvc/<FQDN>:[<port> | <instancename>]

    Where:

    • MSSQLSvc is the service being registered.
    • <FQDN> is the fully qualified domain name of the server.
    • <port> is the TCP port number.
    • <instancename> is the name of the SQL Server instance.
  • Default Instance SPN Format:

    MSSQLSvc/<FQDN>:<port>  
    OR  
    MSSQLSvc/<FQDN>

    Where:

    • MSSQLSvc is the service being registered.
    • <FQDN> is the fully qualified domain name of the server.
    • <port> is the TCP port number.

Managing SPNs for SQL Server Connection Issues

If you encounter connection problems with SQL Server related to SPNs, you can manage SPNs using the SetSPN command-line utility:

  • To list SPNs for a particular domain account:

    SetSPN -L domain\account
  • To create or add a new SPN:

    SetSPN -A MSSQLSvc/<SQL Server FQDN>:<port> domain\account

Useful Tool for Troubleshooting Kerberos Issues

Microsoft provides the Kerberos Configuration Manager for SQL Server, a diagnostic utility designed to help identify and resolve Kerberos authentication problems with SQL Server, SQL Server Reporting Services, and SQL Server Analysis Services.

You can download the tool here:
Microsoft Kerberos Configuration Manager for SQL Server

How to change SQL Server collation

How to Change SQL Server Collation After Installation

If you need to change the collation of your SQL Server after installation, you can do so by using the commands below. However, please be aware that this operation can be risky and might impact your environment. It is highly recommended to test these commands in a separate, non-production environment before applying them to your live servers.

Changing Server Collation

To change the server collation, you can start SQL Server in single-user mode with specific trace flags enabled and specify the new collation. Here is an example command:

sqlservr -m -T4022 -T3659 -s"SQL2017" -q"SQL_Latin1_General_CP1_CI_AI"

Explanation of the parameters:

  • -m: Starts SQL Server in single-user admin mode.
  • -T: Enables trace flags at startup.
  • -s: Specifies the SQL Server instance name.
  • -q: Defines the new collation to be applied.

In this example, two trace flags are used:

  • 4022: Bypasses startup procedures in SQL Server.
  • 3659: Enables logging of all errors to the error log during server startup.

Important: Changing server collation affects all system and user databases and can lead to issues if not performed correctly. Always ensure you have a full backup and test thoroughly in a controlled environment.

How to find SQL Server proxy login

Understanding SQL Server Agent Proxy Accounts

In SQL Server, an Agent proxy account provides a specific security context under which a job step can execute. Essentially, each proxy is linked to a security credential, which defines the permissions the job step will use. This is especially useful when you need to control permissions for individual steps within SQL Server Agent jobs.

To assign permissions to a particular job step, you create a proxy with the necessary rights for a SQL Server Agent subsystem and then associate that proxy with the job step.


Viewing Job Steps and Their Proxies

The following query helps you list SQL Server Agent jobs along with their steps and the associated proxy accounts:

---->> List job steps with their assigned proxies
SELECT 
    J.job_id,    
    J.name,    
    S.step_name,    
    S.step_id,    
    P.name AS ProxyName,    
    SP.name AS CredentialUserName,    
    SP.type_desc AS CredentialUserType
FROM 
    msdb.dbo.sysjobs J
    INNER JOIN msdb.dbo.sysjobsteps S ON S.job_id = J.job_id
    LEFT OUTER JOIN msdb.dbo.sysproxies P ON P.proxy_id = S.proxy_id
    LEFT OUTER JOIN sys.server_principals SP ON SP.sid = P.user_sid;

This output shows which proxies are linked to which job steps, including the credential user associated with each proxy.

SQL Server Agent Proxy Example

How to Create a SQL Server Agent Proxy

Here is an example script to create a SQL Server Agent proxy:

  1. Create a Credential that stores the security context (username and password).
  2. Create a Proxy that uses the credential.
  3. Grant the Proxy permission to access a specific subsystem, such as ActiveX Scripting.
-- Step 1: Create a credential
USE msdb;
GO
CREATE CREDENTIAL CatalogApplicationCredential 
WITH IDENTITY = 'REDMOND/TestUser',
SECRET = 'G3$1o)lkJ8HNd!';
GO

-- Step 2: Create a proxy and assign the credential to it
EXEC dbo.sp_add_proxy  
    @proxy_name = 'Catalog application proxy',
    @enabled = 1,
    @description = 'Maintenance tasks on catalog application.',
    @credential_name = 'CatalogApplicationCredential';
GO

-- Step 3: Grant the proxy access to the ActiveX Scripting subsystem (subsystem_id = 2)
EXEC dbo.sp_grant_proxy_to_subsystem  
    @proxy_name = N'Catalog application proxy',
    @subsystem_id = 2;
GO

When to Use SQL Server Agent Proxies

Proxies are generally used within SQL Server Agent jobs to allow specific job steps to run under different security contexts. This is particularly useful when some job steps require elevated or restricted permissions distinct from the SQL Server Agent service account.


Reference

For more detailed information, visit the official Microsoft documentation:
Create a SQL Server Agent Proxy


Using SQL Server Agent proxies helps you secure your automated jobs by controlling the exact permissions under which each step runs. This improves security and allows for more flexible job management.

How to find the currently running queries in SQL Server

 

How to Identify Currently Running Queries in SQL Server

When troubleshooting SQL Server performance issues, one of the key steps is to determine which queries are actively running on the server. Monitoring running queries helps you identify long-running or resource-intensive processes that might be impacting overall performance.

The following T-SQL script is essential for checking the active queries on your SQL Server instance. It provides detailed information about each running query, including the session ID, status, login name, host, blocking session, database, CPU time, start time, elapsed time, and the SQL statement itself.


Script to View Current Running Queries

-- Get information about currently executing queries
SELECT 
    SPID = er.session_id,
    STATUS = ses.status,
    [Login] = ses.login_name,
    Host = ses.host_name,
    BlkBy = er.blocking_session_id,
    DBName = DB_Name(er.database_id),
    CommandType = er.command,
    ObjectName = OBJECT_NAME(st.objectid),
    CPUTime = er.cpu_time,
    StartTime = er.start_time,
    TimeElapsed = CAST(GETDATE() - er.start_time AS TIME),
    SQLStatement = st.text
FROM 
    sys.dm_exec_requests er
OUTER APPLY 
    sys.dm_exec_sql_text(er.sql_handle) st
LEFT JOIN 
    sys.dm_exec_sessions ses ON ses.session_id = er.session_id
LEFT JOIN 
    sys.dm_exec_connections con ON con.session_id = ses.session_id
WHERE 
    st.text IS NOT NULL;

Explanation of Key Columns:

  • SPID: The session ID of the running query.
  • STATUS: Current status of the session.
  • Login: The login name of the user executing the query.
  • Host: The client host name from where the query originated.
  • BlkBy: Session ID of any blocking session.
  • DBName: The database context where the query is running.
  • CommandType: The type of command being executed (e.g., SELECT, INSERT).
  • ObjectName: The object (like a table or procedure) involved in the query.
  • CPUTime: The amount of CPU time used by the query.
  • StartTime: When the query execution started.
  • TimeElapsed: Duration since the query started running.
  • SQLStatement: The actual SQL query text.

Why Use This Script?

This script gives you real-time insight into the workload on your SQL Server instance. By identifying which queries are running and how long they have been executing, you can:

  • Detect blocking and deadlocks caused by long-running queries.
  • Analyze queries consuming excessive CPU.
  • Gain visibility into user activities affecting performance.
  • Assist in tuning and troubleshooting bottlenecks.

Feel free to use and customize this script to suit your monitoring needs. It’s a handy tool for DBAs and developers alike to maintain optimal database performance.

How to find SQL server listening port

 

How to Read SQL Server Error Logs and Find TCP Port Information Using T-SQL

When troubleshooting SQL Server, error logs provide crucial insights into server events, startup messages, and potential issues. Additionally, sometimes you may want to programmatically discover the TCP port on which your SQL Server instance is listening. In this article, we'll cover how to read error logs using T-SQL and how to query the Windows registry to get the SQL Server port number.


Understanding the Parameters for Reading SQL Server Error Logs

The extended stored procedure xp_readerrorlog allows you to read SQL Server error logs with various options. Here’s what the parameters mean:

  1. Error Log File Number:

    • 0 means the current error log file
    • 1 means Archive #1
    • 2 means Archive #2, and so on.
  2. Log File Type:

    • 1 or NULL indicates the SQL Server error log
    • 2 indicates the SQL Server Agent log
  3. Search String 1: The primary string you want to search for in the logs.

  4. Search String 2: A secondary string to refine the search results further.

  5. Start Time: The start date/time to filter the log entries.

  6. End Time: The end date/time to filter the log entries.

  7. Sort Order: Use N'asc' for ascending or N'desc' for descending order of results.


Example: Reading the Current Error Log for a Specific Message

If you want to read the current error log and search for the phrase "Server is listening on", you can run:

xp_readerrorlog 0, 1, N'Server is listening on';

This command will output all entries containing that string from the current SQL Server error log.


Retrieving SQL Server TCP Port from the Registry

SQL Server stores the TCP port it listens on in the Windows registry. Using xp_regread, you can retrieve this port number from within T-SQL.

Here’s a sample script that dynamically builds the registry path based on your server name and service name, reads the TCP port, and displays it:

SELECT @SERVERNAME AS ServerName, @SERVICENAME AS ServiceName;

DECLARE @value VARCHAR(20);
DECLARE @key VARCHAR(100);

IF ISNULL(CHARINDEX('\', @SERVERNAME, 0), 0) > 0
    SET @key = 'SOFTWARE\Microsoft\Microsoft SQL Server\' + @SERVICENAME + '\MSSQLServer\SuperSocketNetLib\Tcp';
ELSE
    SET @key = 'SOFTWARE\MICROSOFT\MSSQLSERVER\MSSQLSERVER\SUPERSOCKETNETLIB\TCP';

SELECT @key AS [RegistryKey];

EXEC master..xp_regread
   @rootkey = 'HKEY_LOCAL_MACHINE',
   @key = @key,
   @value_name = 'TcpPort',
   @value = @value OUTPUT;

SELECT 'Port Number : ' + CAST(@value AS VARCHAR(5)) AS PortNumber;

This script works by:

  • Checking if the server name contains a backslash (indicating a named instance).
  • Setting the registry key path accordingly.
  • Reading the TcpPort value from the registry.
  • Returning the port number in a readable format.

Conclusion

These tools allow SQL Server administrators and developers to efficiently gather important diagnostic information directly via T-SQL. Whether you're searching through error logs for critical messages or discovering configuration details like the SQL Server TCP port, leveraging xp_readerrorlog and xp_regread helps automate and streamline these tasks.

Always exercise caution when accessing the registry and ensure you have the necessary permissions and backups before making any changes.

How to get Service account information in SQL Server using scripts

 

Managing SQL Server Services and Registry Access Using T-SQL

As a SQL Server professional, it's often necessary to gather information about server services or even interact with the Windows registry directly from SQL Server. In this post, we'll explore how to query SQL Server service status and perform registry operations using built-in system views and extended stored procedures.


Querying SQL Server Services

To view details about SQL Server services running on your server, you can use the dynamic management view sys.dm_server_services. This view returns information such as service names, statuses, startup types, and service account names.

Here is a simple query to retrieve all the data from this DMV:

SELECT * FROM sys.dm_server_services;

This query helps you monitor the status and configuration of SQL Server-related services from within your database environment.

For more detailed documentation on this DMV, visit:

sys.dm_server_services (Transact-SQL)


Accessing Windows Registry from SQL Server

SQL Server provides extended stored procedures that enable interaction with the Windows registry. This can be useful for advanced configuration or troubleshooting tasks, but caution is advised since modifying the registry can affect system stability.

Reading Registry Values

You can use xp_regread to read a registry value. For example, to read the ObjectName from a specific services key:

EXEC master.dbo.xp_regread
    'HKEY_LOCAL_MACHINE',
    'SYSTEM\CurrentControlSet\services\',
    'ObjectName';

This retrieves the value of ObjectName from the specified registry path.


Other Registry-Related Commands

Removing a Multi-String Registry Value

To remove a multi-string value from the registry, use xp_regremovemultistring like this:

EXECUTE master..xp_regremovemultistring
  @rootkey = 'HKEY_LOCAL_MACHINE',
  @key = 'SOFTWARETest',
  @value_name = 'TestValue',
  @value = 'Test';

Writing to the Registry

You can write or update registry values using xp_regwrite. The syntax is:

EXEC master.dbo.xp_regwrite
    @rootkey = 'rootkey',
    @key = 'key',
    @value_name = 'value_name',
    @type = 'type', -- Use REG_SZ for strings or REG_DWORD for integers
    @value = 'value';

Replace the parameters with your target registry hive, key path, value name, type, and the new value.


Deleting a Registry Key

Warning: This command deletes an entire registry key and should be used with extreme caution.

EXEC master.dbo.xp_regdeletekey
    @rootkey = 'rootkey',
    @key = 'key';

Deleting a key cannot be undone and may impact system or application stability.


Summary

These built-in SQL Server dynamic management views and extended stored procedures provide powerful ways to monitor and manage server services and interact with the Windows registry directly from T-SQL. Always ensure you have proper backups and understand the implications before modifying the registry.

If you want to dive deeper, the official Microsoft documentation is an excellent resource to explore further.

How to use extended events to catch all error in SQL Server

 

Introduction to SQL Server Extended Events for Performance Monitoring

SQL Server's Extended Events framework is a powerful and flexible system designed to help users gather as much or as little diagnostic data as needed to troubleshoot or analyze performance issues. Its architecture is highly configurable and scales efficiently, making it an essential tool for database administrators.


Benefits of Using Extended Events

Extended Events is a lightweight monitoring mechanism that minimizes the impact on server performance while capturing detailed diagnostic information. SQL Server offers two graphical interfaces that enable users to create, modify, view, and analyze event sessions with ease.


Exploring Extended Events System Views with T-SQL

SQL Server provides several system catalog views to inspect Extended Events sessions and their components. Here are some useful queries to explore event session definitions, fields, actions, targets, and events:

-- List all event session definitions in SQL Server
SELECT * FROM sys.server_event_sessions;

-- List each customizable column explicitly set on events and targets
SELECT * FROM sys.server_event_session_fields;

-- List each action associated with events in a session
SELECT * FROM sys.server_event_session_actions;

-- List each event target for event sessions
SELECT * FROM sys.server_event_session_targets;

-- List all events configured in an event session
SELECT * FROM sys.server_event_session_events;

Creating an Extended Event Session to Capture Errors

The following example demonstrates how to create an Extended Event session that captures all errors with severity greater than 10, along with useful context information such as client application name, hostname, and SQL text:

CREATE EVENT SESSION [CatchError] ON SERVER 
ADD EVENT sqlserver.error_reported(
    ACTION(sqlserver.client_app_name, sqlserver.client_hostname,
           sqlserver.database_id, sqlserver.sql_text, sqlserver.tsql_stack, sqlserver.username)
    WHERE ([severity] > 10))
ADD TARGET package0.event_file(
    SET filename = N'CatchError.xel', 
        max_file_size = 5, 
        max_rollover_files = 5, 
        metadatafile = N'CatchError.xem')
WITH (
    MAX_MEMORY = 4096 KB,
    EVENT_RETENTION_MODE = ALLOW_SINGLE_EVENT_LOSS,
    MAX_DISPATCH_LATENCY = 5 SECONDS,
    MAX_EVENT_SIZE = 0 KB,
    MEMORY_PARTITION_MODE = NONE,
    TRACK_CAUSALITY = OFF,
    STARTUP_STATE = OFF
);
GO

To start this session, run:

ALTER EVENT SESSION CatchError ON SERVER STATE = START;
GO

Querying the Captured Event Data

Once your Extended Event session is running and capturing data, you can query the event files using the following method. This example reads and formats the error information stored in the event files:

;WITH events_cte AS (
    SELECT 
        DATEADD(mi, DATEDIFF(mi, GETUTCDATE(), CURRENT_TIMESTAMP), xevent.event_data.value('(event/@timestamp)[1]', 'datetime2')) AS err_timestamp,
        xevent.event_data.value('(event/data[@name="severity"]/value)[1]', 'bigint') AS err_severity,
        xevent.event_data.value('(event/data[@name="error_number"]/value)[1]', 'bigint') AS err_number,
        xevent.event_data.value('(event/action[@name="client_hostname"]/value)[1]', 'nvarchar(512)') AS client_hostname,
        xevent.event_data.value('(event/action[@name="client_app_name"]/value)[1]', 'nvarchar(512)') AS client_app_name,
        xevent.event_data.value('(event/data[@name="message"]/value)[1]', 'nvarchar(512)') AS err_message,
        xevent.event_data.value('(event/action[@name="sql_text"]/value)[1]', 'nvarchar(max)') AS sql_text,
        xevent.event_data
    FROM sys.fn_xe_file_target_read_file('CatchError*.xel', 'CatchError*.xem', NULL, NULL) AS xevents
    CROSS APPLY (SELECT CAST(event_data AS XML) AS event_data) AS xevent
)
SELECT * 
FROM events_cte
ORDER BY err_timestamp;

Visualizing Extended Events

The Extended Events sessions and their data can also be viewed and managed graphically within SQL Server Management Studio (SSMS). Below is an example screenshot demonstrating the interface:

Extended Events UI Screenshot

Additional Resources

For more detailed information, please refer to the official Microsoft documentation and catalog views:


Using Extended Events allows SQL Server administrators to perform detailed diagnostics while maintaining minimal performance overhead, making it an indispensable tool for effective database management.

How to get SSIS catalog information's

 

Understanding Where SQL Server SSIS Package Information Is Stored

In SQL Server, Integration Services (SSIS) package execution details and related metadata are stored within the SSISDB catalog database. This centralized storage makes managing and monitoring your SSIS packages easier and more efficient.


Querying SSIS Package Execution Details

The following T-SQL query retrieves detailed information about SSIS package executions along with related folder, project, and package metadata stored in the SSISDB catalog:


SELECT E.execution_id, E.folder_name, E.project_name, E.package_name, E.reference_id, E.reference_type, E.environment_folder_name, E.environment_name, E.project_lsn, E.executed_as_sid, E.executed_as_name, E.use32bitruntime, E.operation_type, E.created_time, E.object_type, E.object_id, E.status, E.start_time, E.end_time, E.caller_sid, E.caller_name, E.process_id, E.stopped_by_sid, E.stopped_by_name, E.dump_id, E.server_name, E.machine_name, E.total_physical_memory_kb, E.available_physical_memory_kb, E.total_page_file_kb, E.available_page_file_kb, E.cpu_count, F.folder_id, F.name, F.description, F.created_by_sid, F.created_by_name, F.created_time, P.project_id, P.folder_id, P.name, P.description, P.project_format_version, P.deployed_by_sid, P.deployed_by_name, P.last_deployed_time, P.created_time, P.object_version_lsn, P.validation_status, P.last_validation_time, PKG.package_id, PKG.name, PKG.package_guid, PKG.description, PKG.package_format_version, PKG.version_major, PKG.version_minor, PKG.version_build, PKG.version_comments, PKG.version_guid, PKG.project_id, PKG.entry_point, PKG.validation_status, PKG.last_validation_time FROM SSISDB.catalog.executions AS E INNER JOIN SSISDB.catalog.folders AS F ON F.name = E.folder_name INNER JOIN SSISDB.catalog.projects AS P ON P.folder_id = F.folder_id AND P.name = E.project_name INNER JOIN SSISDB.catalog.packages AS PKG ON PKG.project_id = P.project_id AND PKG.name = E.package_name;

This query joins executions with their respective folders, projects, and packages to provide a comprehensive overview of SSIS activity.


How to Create the SSISDB Catalog in SQL Server Management Studio

If the SSISDB catalog is not yet created on your server, follow these steps to set it up:

  1. Open SQL Server Management Studio (SSMS).

  2. Connect to your SQL Server Database Engine instance.

  3. In Object Explorer, expand the server node.

  4. Right-click on Integration Services Catalogs and select Create Catalog.

  5. Enable CLR Integration as the catalog requires CLR stored procedures.

  6. Enable automatic execution of Integration Services stored procedures at SQL Server startup. This option runs the catalog.startup stored procedure each time the SQL Server instance restarts, ensuring that the catalog’s operation state is properly maintained and fixing the status of any running packages if the server was previously shut down unexpectedly.

  7. Set a password for the encryption key used by the catalog, then click OK to complete the creation.


Additional Resources


This setup and querying approach gives you control and insight into your SSIS environment, helping you manage package deployments and executions effectively.

How to find login information in SQL Server using T-SQL

 

Generating Scripts Using T-SQL Statements

When working with SQL Server, generating scripts to recreate logins, roles, and permissions can be a crucial task. Below are some useful T-SQL scripts that can help automate this process.


Script to Generate Logins

The following script generates the creation scripts for SQL Server logins. Note that the output can return up to 8192 characters per batch.


SELECT 
  'IF (SUSER_ID(' + QUOTENAME(SP.name, '''') + ') IS NULL) BEGIN CREATE LOGIN ' + QUOTENAME(SP.name) +
  CASE 
    WHEN SP.type_desc = 'SQL_LOGIN' THEN 
      ' WITH PASSWORD = ' + CONVERT(NVARCHAR(MAX), SL.password_hash, 1) + ' HASHED, CHECK_EXPIRATION = ' + 
      CASE WHEN SL.is_expiration_checked = 1 THEN 'ON' ELSE 'OFF' END + 
      ', CHECK_POLICY = ' + CASE WHEN SL.is_policy_checked = 1 THEN 'ON,' ELSE 'OFF,' END
    ELSE ' FROM WINDOWS WITH'
  END + 
  ' DEFAULT_DATABASE=[' + SP.default_database_name + '], DEFAULT_LANGUAGE=[' + SP.default_language_name + '] END;' 
  COLLATE SQL_Latin1_General_CP1_CI_AS -- Logins To Be Created --
FROM sys.server_principals AS SP
LEFT JOIN sys.sql_logins AS SL ON SP.principal_id = SL.principal_id
WHERE SP.type IN ('S', 'G', 'U')
  AND SP.name NOT LIKE '##%##'
  AND SP.name NOT LIKE 'NT AUTHORITY%'
  AND SP.name NOT LIKE 'NT SERVICE%'
  AND SP.name <> 'sa';

This script checks for existing logins and creates them if they do not exist, including their password hash and policy settings.


Script to Generate Role Memberships

To recreate server role memberships, use the following script. It generates commands to add logins to their respective server roles.


-- Scripting Out the Role Membership to Be Added
SELECT 
  'EXEC master..sp_addsrvrolemember @loginame = N''' + SL.name + ''', @rolename = N''' + SR.name + ''''
  AS -- Server Roles the Logins Need to be Added --
FROM master.sys.server_role_members SRM
JOIN master.sys.server_principals SR ON SR.principal_id = SRM.role_principal_id
JOIN master.sys.server_principals SL ON SL.principal_id = SRM.member_principal_id
WHERE SL.type IN ('S', 'G', 'U')
  AND SL.name NOT LIKE '##%##'
  AND SL.name NOT LIKE 'NT AUTHORITY%'
  AND SL.name NOT LIKE 'NT SERVICE%'
  AND SL.name <> 'sa';

This script will generate the necessary commands to restore server role memberships for the users.


Script to Generate Permissions

Finally, to script out the permissions granted at the server level, you can use the following:


-- Scripting out the Permissions to Be Granted
SELECT 
  CASE WHEN SrvPerm.state_desc <> 'GRANT_WITH_GRANT_OPTION' THEN SrvPerm.state_desc 
       ELSE 'GRANT' 
  END + ' ' + SrvPerm.permission_name + ' TO [' + SP.name + ']'
  + CASE WHEN SrvPerm.state_desc <> 'GRANT_WITH_GRANT_OPTION' THEN '' 
         ELSE ' WITH GRANT OPTION' END 
  COLLATE database_default AS -- Server Level Permissions to Be Granted -- 
FROM sys.server_permissions AS SrvPerm 
JOIN sys.server_principals AS SP ON SrvPerm.grantee_principal_id = SP.principal_id 
WHERE SP.type IN ('S', 'U', 'G') 
  AND SP.name NOT LIKE '##%##' 
  AND SP.name NOT LIKE 'NT AUTHORITY%' 
  AND SP.name NOT LIKE 'NT SERVICE%' 
  AND SP.name <> 'sa';

This query lists all server-level permissions, including those granted with the grant option, for the relevant principals.


By using these scripts, you can effectively generate T-SQL scripts to migrate or backup SQL Server security configurations such as logins, role memberships, and permissions.

How to create a login trigger

 

Monitoring Server Logins and Using Server Triggers in SQL Server

It is crucial to ensure that you are not unintentionally blocking all users from connecting to your SQL Server instance. Proper monitoring helps maintain accessibility and security.

One useful way to monitor login activity and server events is through server-level triggers. Below, we explore how to check existing server triggers and create a logon auditing mechanism.


Checking Server Triggers

To see what server triggers are currently active on your SQL Server, run the following query:

SELECT * FROM sys.server_triggers;

This will provide details about all server-level triggers configured on your instance.


Creating a Logon Auditing Table and Trigger

You can audit login events by creating a table to store logon details and a server trigger that captures login activity.

Step 1: Create a Logon Auditing Table


CREATE TABLE LogonAuditing
(
    SessionId INT,
    LogonTime DATETIME,
    HostName VARCHAR(50),
    ProgramName VARCHAR(500),
    LoginName VARCHAR(50),
    ClientHost VARCHAR(50),
    eveData XML
);
GO

This table will record essential information about each login session.

Step 2: Create a Logon Audit Trigger


CREATE TRIGGER [LogonAuditTrigger] 
ON ALL SERVER 
WITH EXECUTE AS 'sa' 
FOR LOGON  
AS
BEGIN
    DECLARE @TrgData XML = EVENTDATA();
    BEGIN TRY
        IF EXISTS (SELECT 1 FROM sys.tables WHERE name = 'LogonAuditing')
        BEGIN
            INSERT INTO [dbo].[LogonAuditing] (SessionId, LogonTime, HostName, ProgramName, LoginName, ClientHost)
            SELECT 
                @SPID,
                @TrgData.value('(/EVENT_INSTANCE/PostTime)[1]', 'DATETIME'),
                HOST_NAME(),
                APP_NAME(),
                @TrgData.value('(/EVENT_INSTANCE/LoginName)[1]', 'VARCHAR(50)'),
                @TrgData.value('(/EVENT_INSTANCE/ClientHost)[1]', 'VARCHAR(50)');
        END
    END TRY
    BEGIN CATCH
        -- Handle errors silently or log if necessary
    END CATCH
END;

This trigger records login events and their details into the LogonAuditing table each time a login occurs.


Additional Resources

For more in-depth exploration on using tables instead of triggers, managing multiple triggers, understanding object dependencies, and working with assemblies in SQL Server, check out these articles by Himanshu Patel:

Popular Posts