开发者

Origin of warning message in sql server

I'm getting warnings like these when running a stored procedure:

Warning: Null value is eliminated by an aggregate or other SET operation开发者_开发百科.

I know what the warning means, but what stored procedure and line number is causing it?

The thing is that the stored procedure is gigantic and calls a dozen other procedures. So it becomes very hard to localize the problem when SQL Server doesn't give you the line number and procedure name where the warning originates. This is using SQL Server 2008.


you have ansi warnings on and an aggregate (sum, max, min, ...) on a column which contains a null value.

You can set ansi_warnings off but better to remove the nulls

e.g. sum(coalesce(col,0))


You can use Extended Events for this.

1) Create and Start the Session

/*Create Extended Events Session*/

IF EXISTS(SELECT * FROM sys.server_event_sessions WHERE name='WarningLogger')
    DROP EVENT SESSION [WarningLogger] ON SERVER;
CREATE EVENT SESSION [WarningLogger]
ON SERVER
ADD EVENT sqlserver.error_reported(
     ACTION (sqlserver.plan_handle, sqlserver.sql_text, sqlserver.tsql_stack)
     WHERE (([severity]=(10))))
ADD TARGET package0.ring_buffer
WITH (MAX_MEMORY = 4096KB, EVENT_RETENTION_MODE = ALLOW_MULTIPLE_EVENT_LOSS, MAX_DISPATCH_LATENCY = 1 SECONDS, MAX_EVENT_SIZE = 0KB, MEMORY_PARTITION_MODE = NONE, TRACK_CAUSALITY = OFF, STARTUP_STATE = OFF)

/*Start the Session*/
ALTER EVENT SESSION [WarningLogger] ON SERVER STATE = START 

2) Test

CREATE PROC #baz 
AS 
declare @g int
select sum(@g)
waitfor delay '00:00:02'

Go
CREATE PROC #bar AS EXEC #baz

GO
CREATE PROC #foo AS EXEC #bar

GO
EXEC #foo

Get the Results

DECLARE 
    @session_name VARCHAR(200) = 'WarningLogger';


with pivoted_data AS(
    SELECT 
        MIN(event_name) as event_name, 
        MIN(event_timestamp) as event_timestamp, 
        unique_event_id, 
        CONVERT 
        ( 
            INT, 
            MIN 
            ( 
                CASE 
                    WHEN 
                        event_name = 'error_reported' and 
                        d_name = 'error' and 
                        d_package IS NULL 
                            THEN d_value
                END 
            ) 
        ) AS [error_reported.error],
        CONVERT 
        ( 
            VARCHAR(MAX), 
            MIN 
            ( 
                CASE 
                    WHEN 
                        event_name = 'error_reported' and 
                        d_name = 'message' and 
                        d_package IS NULL 
                            THEN d_value
                END 
            ) 
        ) AS [error_reported.message],
        CONVERT 
        ( 
            VARCHAR(MAX), 
            MIN 
            ( 
                CASE 
                    WHEN 
                        event_name = 'error_reported' and 
                        d_name = 'plan_handle' and 
                        d_package IS NOT NULL 
                            THEN d_value
                END 
            ) 
        ) AS [error_reported.plan_handle],
        CONVERT 
        ( 
            INT, 
            MIN 
            ( 
                CASE 
                    WHEN 
                        event_name = 'error_reported' and 
                        d_name = 'severity' and 
                        d_package IS NULL 
                            THEN d_value
                END 
            ) 
        ) AS [error_reported.severity],
        CONVERT 
        ( 
            VARCHAR(MAX), 
            MIN 
            ( 
                CASE 
                    WHEN 
                        event_name = 'error_reported' and 
                        d_name = 'sql_text' and 
                        d_package IS NOT NULL 
                            THEN d_value
                END 
            ) 
        ) AS [error_reported.sql_text],
        CONVERT 
        ( 
            INT, 
            MIN 
            ( 
                CASE 
                    WHEN 
                        event_name = 'error_reported' and 
                        d_name = 'state' and 
                        d_package IS NULL 
                            THEN d_value
                END 
            ) 
        ) AS [error_reported.state],
        CONVERT 
        ( 
            XML, 
            MIN 
            ( 
                CASE 
                    WHEN 
                        event_name = 'error_reported' and 
                        d_name = 'tsql_stack' and 
                        d_package IS NOT NULL 
                            THEN d_value
                END 
            ) 
        ) AS [error_reported.tsql_stack],
        CONVERT 
        ( 
            VARCHAR(MAX), 
            MIN 
            ( 
                CASE 
                    WHEN 
                        event_name = 'error_reported' and 
                        d_name = 'user_defined' and 
                        d_package IS NULL 
                            THEN d_value
                END 
            ) 
        ) AS [error_reported.user_defined]
    FROM 
    ( 
        SELECT 
            *, 
            CONVERT(VARCHAR(400), NULL) AS attach_activity_id 
        FROM 
        ( 
            SELECT 
                event.value('(@name)[1]', 'VARCHAR(400)') as event_name, 
                event.value('(@timestamp)[1]', 'DATETIME') as event_timestamp, 
                DENSE_RANK() OVER (ORDER BY event) AS unique_event_id, 
                n.value('(@name)[1]', 'VARCHAR(400)') AS d_name, 
                n.value('(@package)[1]', 'VARCHAR(400)') AS d_package, 
                n.value('((value)[1]/text())[1]', 'VARCHAR(MAX)') AS d_value, 
                n.value('((text)[1]/text())[1]', 'VARCHAR(MAX)') AS d_text 
            FROM 
            ( 
                SELECT 
                    ( 
                        SELECT 
                            CONVERT(xml, target_data) 
                        FROM sys.dm_xe_session_targets st 
                        JOIN sys.dm_xe_sessions s ON 
                            s.address = st.event_session_address 
                        WHERE 
                            s.name = @session_name 
                            AND st.target_name = 'ring_buffer' 
                    ) AS [x] 
                FOR XML PATH(''), TYPE 
            ) AS the_xml(x) 
            CROSS APPLY x.nodes('//event') e (event) 
            CROSS APPLY event.nodes('*') AS q (n) 
        ) AS data_data 
    ) AS activity_data 
    GROUP BY 
        unique_event_id 
),
        StackData AS
        ( SELECT 
            pivoted_data.*,
            frame_xml.value('(./@level)', 'int')      AS [frame_level],
            frame_xml.value('(./@handle)', 'varchar(MAX)') AS [sql_handle],
            frame_xml.value('(./@offsetStart)', 'int')     AS [offset_start],
            frame_xml.value('(./@offsetEnd)', 'int')       AS [offset_end]
        FROM pivoted_data CROSS APPLY [error_reported.tsql_stack].nodes('//frame') N (frame_xml)
        )

   SELECT unique_event_id, [frame_level], sd.[error_reported.message],event_timestamp,sd.[error_reported.sql_text],
        object_name(st.objectid, st.dbid) AS ObjectName,
        SUBSTRING(st.text, (sd.offset_start/2)+1, ((
                CASE sd.offset_end
                    WHEN -1
                    THEN DATALENGTH(st.text)
                    ELSE sd.offset_end
                END - sd.offset_start)/2) + 1) AS statement_text,
        qp.query_plan,
        qs2.creation_time,
        qs2.last_execution_time,
        qs2.execution_count
    FROM StackData AS sd CROSS APPLY sys.dm_exec_sql_text(CONVERT(VARBINARY(MAX),sd.sql_handle,1)) AS st
        LEFT OUTER JOIN sys.dm_exec_query_stats qs2
        ON  qs2.sql_handle = CONVERT(VARBINARY(MAX),sd.sql_handle,1) OUTER APPLY sys.dm_exec_query_plan(CONVERT(VARBINARY(MAX),qs2.plan_handle,1)) AS qp
        WHERE st.text NOT LIKE '%this_query%'
        ORDER BY unique_event_id ASC, [frame_level] DESC


Capture running the main proc in a Trace file.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜