Cách xác định truy vấn cơ sở dữ liệu chéo trong SQL Server


7

Để chuẩn bị cho một dự án di chuyển, chúng tôi đang cố gắng xác định bất kỳ truy vấn nào chọn dữ liệu trên cơ sở dữ liệu.

Điều này có thể có dạng:

SELECT fieldA, fieldB
FROM dbo.TableA a
JOIN DatabaseB.dbo.TableB b ON b.ID = a.ID

hoặc là

DECLARE @resultFromDatabaseB VARCHAR(50)

SELECT @resultFromDatabaseB = b.ID
FROM DatabaseB.dbo.TableB

SELECT fieldA, fieldB
FROM dbo.TableA a
WHERE a.ID = @resultFromDatabaseB

hoặc bất kỳ biến thể nào khác (bao gồm cả INSERTS / CẬP NHẬT / vv ...)

Thật không may, phần lớn các truy vấn không được lưu trữ thủ tục nên tôi không thể phân tích tĩnh văn bản SQL, kế hoạch hiện tại của tôi gọi để ghi lại văn bản truy vấn được lưu trong bộ nhớ cache và thực hiện phân tích tĩnh trên chúng.

Có bất kỳ sự thay thế cho phương pháp này? tức là: sử dụng các sự kiện mở rộng / theo dõi / kiểm toán?

Câu trả lời:


3

Tôi sẽ thiết lập một phiên Sự kiện mở rộng để nắm bắt các sự kiện đã thu được và truyền phát các sự kiện bằng API.

Trước hết phiên:

CREATE EVENT SESSION crossdb ON SERVER 
ADD EVENT sqlserver.lock_acquired(
    SET collect_database_name=(1),collect_resource_description=(1)
    ACTION(
        sqlserver.request_id,sqlserver.session_id,
        sqlserver.sql_text,sqlserver.tsql_frame
    )
    WHERE (
            [package0].[equal_boolean]([sqlserver].[is_system], (0)) -- user SPID
        AND [package0].[equal_uint64]([resource_type], (5)) -- OBJECT
        AND [package0].[not_equal_uint64]([database_id], (32767))  -- resourcedb
        AND [package0].[greater_than_uint64]([database_id], (4)) -- user database
        AND [package0].[greater_than_equal_int64]([object_id], (245575913)) -- user object
        AND (
               [mode] = (1) -- SCH-S
            OR [mode] = (6) -- IS
            OR [mode] = (8) -- IX
            OR [mode] = (3) -- S
            OR [mode] = (5) -- X
        )
        AND [database_name] <> N'distribution'
    )
)
WITH (
    MAX_MEMORY=4096 KB,
    EVENT_RETENTION_MODE=ALLOW_SINGLE_EVENT_LOSS,
    MAX_DISPATCH_LATENCY=30 SECONDS,
    MAX_EVENT_SIZE=0 KB,
    MEMORY_PARTITION_MODE=NONE,
    TRACK_CAUSALITY=OFF,
    STARTUP_STATE=OFF
)
GO

Sau đó, bạn có thể nhóm các sự kiện trên transaction_idtsql_frame. Các nhóm chạm nhiều hơn một nhóm là nhóm database_idphát hành các câu lệnh cơ sở dữ liệu chéo. Sau đó, bạn có thể trích xuất câu lệnh từ sql_texthành động, sử dụng offsetStartoffsetEndtừ tsql_frame.

nhập mô tả hình ảnh ở đây

Tôi có một ví dụ tương tự trên blog của mình ở đây: https://spaghettidba.com/2015/04/20/tracking-table-usage-and-identifying-unuse-objects/


Vì đây là cho SQL 2008R2, hành động sqlserver.tsql_frame không khả dụng. Tôi cũng sẽ cần mở rộng những gì đang bị bắt để bao gồm tên ứng dụng khách và máy chủ khách.
Andrew Bickerton

Bạn sẽ chỉ cần tsql_frame nếu bạn cần chia nhỏ nó ở cấp độ câu lệnh, nhưng có lẽ bạn vẫn ổn ở cấp độ lô. Tên ứng dụng và tên máy chủ nên có sẵn trong năm 2008R2, nhưng tôi không có ví dụ để kiểm tra, xin lỗi
spaghettidba

cảm ơn, tôi sẽ chỉnh sửa câu trả lời của bạn để kết hợp những khác biệt đó (một khi tôi đã kiểm tra nó) - cảm ơn :-)
Andrew Bickerton
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.