小编Rit*_*kre的帖子

在不使用触发器的情况下查找在 SQL Server 中触发查询的客户端的身份?

我目前正在使用更改数据捕获 (CDC)来跟踪数据更改,并且我希望跟踪提交进行更改的查询的客户端的主机名和 IP 地址。如果有 5 个不同的客户端通过相同的用户名登录,一个人面临着跟踪这 5 个中哪一个触发了查询的难题。我发现的其他似是而非的解决方案包括使用以下命令更改 CDC 表:

ALTER TABLE cdc.schema_table_CT 
ADD HostName nvarchar(50) NULL DEFAULT(HOST_NAME())
Run Code Online (Sandbox Code Playgroud)

但是,这将返回触发查询的服务器的主机名,而不是触发查询的客户端的主机名。

有没有办法解决这个问题?有助于记录客户端的主机名或 IP 地址(或某种其他类型的唯一身份)的东西。我不想使用触发器,因为它会减慢系统速度,而且 CDC 还会生成系统表,因此显然不可能使用触发器。

sql-server audit sql-server-2012 change-data-capture

12
推荐指数
1
解决办法
6927
查看次数

为什么删除小数列不会释放任何空间?

我有几个表,每个表都有几列数据类型为十进制的列。我决定删除这些列以释放一些空间。我使用ALTER TABLE DROP COLUMN col1了相同的命令。但是,我无法查看正在释放的任何空间。为什么会这样,因为 Decimal 不是可变长度列,应该立即释放空间?

附注。这是我用来跟踪可用空间量的查询:

SELECT
b.groupname AS 'File Group',
Name,
[Filename],
CONVERT (Decimal(15,2),ROUND(a.Size/128.000,2)) [Currently Allocated Space (MB)],
CONVERT (Decimal(15,2),ROUND(FILEPROPERTY(a.Name,'SpaceUsed')/128.000,2)) AS [Space Used (MB)],
CONVERT (Decimal(15,2),ROUND((a.Size-FILEPROPERTY(a.Name,'SpaceUsed'))/128.000,2)) AS [Available Space (MB)],
'DBCC SHRINKFILE ('''+Name+''','+CAST(CONVERT (Decimal(15,2),ROUND((FILEPROPERTY(a.Name,'SpaceUsed'))/128.000,2)) AS VARCHAR(10))+')' QUERY
FROM dbo.SYSFILES a (NOLOCK)
JOIN SYSFILEGROUPS b (NOLOCK)
ON a.groupid = b.groupid
ORDER BY b.groupname
Run Code Online (Sandbox Code Playgroud)

sql-server disk-space

5
推荐指数
1
解决办法
260
查看次数

SQL Server Audit 能否用于跟踪对表执行 DML 的用户的主机名或 IP 地址?

我一直在阅读有关 SQL Server 审计的文章,到目前为止,我已经理解它跟踪已执行的命令以及其他一些附加信息(SPID、对象 ID 和其他内容)。但这是否可以用于唯一标识执行此操作的个人,或执行命令的计算机的某种类型的唯一 ID,例如主机名或 IP 地址?

如果它不能唯一识别机器或执行命令的人,我只是不想浪费时间阅读它。

sql-server audit

4
推荐指数
1
解决办法
7532
查看次数

如何防止扩展事件跟踪系统触发的事件?

我使用了扩展事件来跟踪在特定数据库中的表上执行的 DML 和 DDL 操作。除此之外,我还跟踪用户(现在我是唯一用户)在被跟踪的数据库中执行的过程。我正在使用事件“sql_statement_completed”。它捕获所有成功完成的 sql 语句,然后我过滤语句以仅存储 Insert、Update、Delete 和 Drop 语句(也存储 exec 语句)。下面是与之相关的代码:

CREATE EVENT SESSION <track> ON SERVER
ADD EVENT sqlserver.sql_statement_completed(
    ACTION(sqlserver.client_hostname,
           sqlserver.sql_text,
           sqlserver.username)
    WHERE ([sqlserver].[database_name]= <database_name> 
    AND [sqlserver].[is_system]=(0) 
    AND (([statement] like 'INSERT%' 
       OR [statement] like 'UPDATE%' 
       OR [statement] like 'DELETE%' 
       OR [statement] like 'DROP%' 
       OR [statement] like 'ALTER%' 
       OR [statement] like 'EXEC%')))) 
ADD TARGET package0.event_file(
    SET filename=N'C:\ExtendedEvents\track.xel',
    max_file_size=(102400),
    max_rollover_files=(10000),
    metadatafile=N'C:\ExtendedEvents\track.xem')
WITH (MAX_MEMORY=1048576 KB,
      EVENT_RETENTION_MODE=NO_EVENT_LOSS,
      MAX_DISPATCH_LATENCY=5 SECONDS,
      MAX_EVENT_SIZE=0 KB,
      MEMORY_PARTITION_MODE=NONE,
      TRACK_CAUSALITY=OFF,
      STARTUP_STATE=ON)
Run Code Online (Sandbox Code Playgroud)

现在,虽然这一直在跟踪正在针对数据库中的表执行的 DML 和 DDL 语句,但它也一直在跟踪一些没有被用户直接执行的语句(特别是一些似乎已被用户执行的过程语句)系统本身)。

下图包含了已跟踪的语句(不是直接解雇用户):

在此处输入图片说明

尽管这是事实,我已经明确地设置 …

sql-server extended-events

3
推荐指数
1
解决办法
1629
查看次数

确定 DDL 触发器中的命令类型/获取新列的名称和数据类型

给定与 DDL 命令对应的字符串,我如何确定它是哪个 DDL 命令(列添加、约束添加等)?

我在数据库上有一个 DDL 触发器,只要数据库中的任何表被更改,就会触发它;系统表将记录在数据库中的任何表上触发的 DDL 命令。

所以命令看起来像:

1. ALTER TABLE [dbo.table] ADD [column] VARCHAR(20) NULL;
2. ALTER TABLE [dbo.table] ADD [column] VARCHAR(20) NULL CONSTRAINT [cons] UNIQUE;
3. ALTER TABLE [dbo.table] WITH NOCHECK ADD CONSTRAINT [cons] CHECK ([column] > 1);
4. ALTER TABLE [dbo.table] WITH NOCHECK ADD [column1] VARCHAR(20) NULL,
   CONSTRAINT [cons] CHECK ([column] > 1);
Run Code Online (Sandbox Code Playgroud)

以上4条DDL语句有什么办法辨别吗?我只对将新列添加到表中的 DDL 感兴趣,并且希望仅检索此新列的名称和数据类型。

到目前为止,我一直在使用诸如SUBSTRING(), 之类的函数LEN()CHARINDEX()但运气不佳。

附言。我的触发器能够获取正在执行 DDL 的表的名称。

触发器将简单地将上述 4 个选项之一作为输入,并且需要区分何时发生了列更改,并且只检索新列名及其对应的数据类型。

在对表进行更改之后,触发器将被触发,这个确切的更改命令被记录在一个系统表中,作为我用来跟踪更改的 CDC 功能的一部分(限制我对命令的访问)。这个 CDC …

trigger sql-server audit t-sql ddl

2
推荐指数
1
解决办法
1091
查看次数

寻求有关扩展事件行为的帮助

我正在使用扩展事件来跟踪服务器上正在执行的过程及其执行程序的主机名。

我使用了以下 XE 脚本:

CREATE EVENT SESSION [EXEC_SP] ON SERVER 
ADD EVENT sqlserver.sp_statement_completed
(
  SET collect_statement=(0)
  ACTION
  (
    sqlserver.client_hostname,sqlserver.database_id,sqlserver.database_name,
    sqlserver.nt_username,sqlserver.server_instance_name,
    sqlserver.server_principal_name,sqlserver.session_id,sqlserver.sql_text,
    sqlserver.transaction_id,sqlserver.username
  )
  WHERE ( [sqlserver].[is_system]=(0))
)
 ADD TARGET package0.asynchronous_file_target
 (
   SET FILENAME = N'C:\EXEC_SP.xel',
   METADATAFILE = N'C:\EXEC_SP.xem'
 )
 WITH
 (
   MAX_MEMORY=4096KB,
   EVENT_RETENTION_MODE=NO_EVENT_LOSS,
   MAX_DISPATCH_LATENCY=15 SECONDS,
   TRACK_CAUSALITY=OFF,
    STARTUP_STATE=ON
 );
Run Code Online (Sandbox Code Playgroud)

但是,正在执行的过程主体内的每个语句都在目标处构成一行。

例如,如果我的程序主体中有 5 个语句,则该事件将被触发 5 次,并且在目标处将有 5 个不同的条目对应于相同的条目。

我只为每个正在执行的过程寻找一个条目,而不是多个条目。

也就是说,正在执行的每个过程都应该只构成 1 行而不是多行。

如何解决这个问题?

sql-server extended-events sql-server-2012

2
推荐指数
1
解决办法
194
查看次数