跟踪准备好的 SQL 语句中的错误

car*_*reo 5 sql-server prepared-statement sql-server-2016

我使用扩展事件来存储数据库错误,如下所示:

CREATE EVENT SESSION [ErrorCapture] 
ON SERVER 
ADD EVENT sqlserver.error_reported
(
    ACTION
    (
        sqlserver.client_hostname,
        sqlserver.database_id,
        sqlserver.sql_text,
        sqlserver.username
    )
    WHERE 
    (
        [severity] >= (11)
    )
) 
ADD TARGET package0.asynchronous_file_target
(
    SET filename='J:\ServerXmlOutput\ErrorCapture.xel'
)
WITH 
(
    MAX_MEMORY=4096 KB,
    EVENT_RETENTION_MODE=ALLOW_SINGLE_EVENT_LOSS,
    MAX_DISPATCH_LATENCY=10 SECONDS,
    MAX_EVENT_SIZE=0 KB,
    MEMORY_PARTITION_MODE=NONE,
    TRACK_CAUSALITY=OFF,
    STARTUP_STATE=ON
);
Run Code Online (Sandbox Code Playgroud)

这有助于我轻松跟踪导致它们的应用程序。我有类似的东西来跟踪慢查询和其他特殊情况。但是,我从 SQL Server Profiles 中注意到 PHP/Laravel 应用程序不是直接发送一些语句,而是使用 RPC:Completed:它们看起来像准备好的语句,在运行时接收参数。如何扩展我的 ErrorCapture 以包含由通过 RPC:Completed 执行的语句引起的错误?

Han*_*dyD 4

您拥有的代码确实从准备好的语句中返回错误。下面的 PowerShell 针对 SQL Server 执行准备好的语句,该语句会故意失败。这会出现在 Profiler 中并带有 RPC:Completed,如您所描述的:

$SqlConn = [System.Data.SqlClient.SqlConnection]::New("Server=localhost;Database=master;Trusted_connection=true;")

$SqlConn.Open()

$SqlCmd = [System.Data.SqlClient.SqlCommand]::New($null, $SqlConn)

$SqlCmd.CommandText = "SELECT @Val/0"

$idParam = [System.Data.SqlClient.SqlParameter]::New("@Val", [System.Data.SqlDbType]::Int, 0);
$idParam.Value = 1;
$SqlCmd.Parameters.Add($idParam);

$SqlCmd.Prepare()
$SqlCmd.ExecuteNonQuery()

$SqlConn.Close()
Run Code Online (Sandbox Code Playgroud)

当我在 Profiler 和扩展事件会话运行的情况下运行此程序时,我可以看到这两个工具中报告的错误:

延伸活动:

扩展活动

分析器:

分析器

一个问题可能是这些消息的严重性低于 11,因此您的 EE 会话将它们排除在外。如果您使用 TSQL_Replay 模板运行探查器跟踪并在错误和警告下包含“用户错误消息” ,那么准备好的语句中的错误是否会出现?

如果是这样,请检查Profiler 中的错误列,并对 SQL Server 运行以下命令,将 8134 替换为 Profiler 中的错误号:

SELECT * FROM sys.messages WHERE message_id = 8134
Run Code Online (Sandbox Code Playgroud)

检查其中的严重性列,以确定准备好的语句返回的错误的严重性。