Cách xem lịch sử truy vấn trong SQL Server Management Studio


159

Là lịch sử truy vấn được lưu trữ trong một số tệp nhật ký? Nếu có, bạn có thể cho tôi biết làm thế nào để tìm vị trí của họ? Nếu không, bạn có thể cho tôi lời khuyên về cách xem nó?


1
http://www.ssmstoolspack.com/ cung cấp một cửa sổ lịch sử nếu đó là những gì bạn đang theo đuổi.
TI

Câu trả lời:


226

[Vì câu hỏi này có thể sẽ được đóng lại dưới dạng trùng lặp.]

Nếu SQL Server chưa được khởi động lại (và kế hoạch chưa bị đuổi, v.v.), bạn có thể tìm thấy truy vấn trong bộ đệm của kế hoạch.

SELECT t.[text]
FROM sys.dm_exec_cached_plans AS p
CROSS APPLY sys.dm_exec_sql_text(p.plan_handle) AS t
WHERE t.[text] LIKE N'%something unique about your query%';

Nếu bạn bị mất tệp vì Management Studio bị sập, bạn có thể tìm thấy các tệp khôi phục tại đây:

C:\Users\<you>\Documents\SQL Server Management Studio\Backup Files\

Nếu không, bạn sẽ cần sử dụng một cái gì đó khác để giúp bạn lưu lịch sử truy vấn của mình, như Gói công cụ SSMS như được đề cập trong câu trả lời của Ed Harper - mặc dù nó không miễn phí trong SQL Server 2012+. Hoặc bạn có thể thiết lập một số dấu vết nhẹ được lọc trên tên đăng nhập hoặc tên máy chủ của mình (nhưng vui lòng sử dụng theo dõi phía máy chủ, không phải Profiler, cho việc này).


Như @ Nenad-Zivkovic đã nhận xét, có thể hữu ích khi tham gia sys.dm_exec_query_statsvà đặt hàng bằng cách last_execution_time:

SELECT t.[text], s.last_execution_time
FROM sys.dm_exec_cached_plans AS p
INNER JOIN sys.dm_exec_query_stats AS s
   ON p.plan_handle = s.plan_handle
CROSS APPLY sys.dm_exec_sql_text(p.plan_handle) AS t
WHERE t.[text] LIKE N'%something unique about your query%'
ORDER BY s.last_execution_time DESC;

9
Cũng có thể giúp tham gia sys.dm_exec_query_statsvà tìm kiếm hoặc đặt hàng trướclast_execution_time
Nenad Zivkovic

Không hoạt động với máy chủ sql 2000 và hoạt động từ máy chủ sql 2005
Durai Amuthan.H

@Duraiamuthan Chà, câu hỏi đặt ra về Management Studio, vì vậy nó sẽ an toàn khi đoán năm 2005+. 2000 không có Studio quản lý, nó có Trình phân tích truy vấn. 2000 cũng là nhiều năm ra khỏi hỗ trợ. Nếu bạn muốn giải quyết vấn đề này cho SQL Server 2000, có lẽ bạn nên hỏi một câu hỏi mới được gắn thẻ với phiên bản cụ thể đó (nếu một bản sao không tồn tại, mà tôi đã không kiểm tra).
Aaron Bertrand

1
@AaronBertrand Nhận xét của tôi là bổ sung cho câu trả lời của bạn. Nó sẽ giúp đỡ người khác
Durai Amuthan.H

3
@AaronBertrand Bạn là một vị thần giữa những người đàn ông.
AnotherDeveloper

49

Muộn nhưng hy vọng có ích vì nó bổ sung thêm chi tiết

Không có cách nào để xem các truy vấn được thực hiện trong SSMS theo mặc định. Có một số lựa chọn mặc dù.

Đọc nhật ký giao dịch - đây không phải là một điều dễ dàng vì nó ở định dạng độc quyền. Tuy nhiên, nếu bạn cần xem các truy vấn đã được thực hiện trong lịch sử (ngoại trừ CHỌN) thì đây là cách duy nhất.

Bạn có thể sử dụng các công cụ của bên thứ ba cho việc này như ApexSQL LogSQL Log Rescue (chỉ miễn phí nhưng chỉ có SQL 2000). Kiểm tra chủ đề này để biết thêm chi tiết tại đây Trình khám phá / phân tích nhật ký giao dịch SQL Server

Trình cấu hình SQL Server - phù hợp nhất nếu bạn chỉ muốn bắt đầu kiểm toán và bạn không quan tâm đến những gì đã xảy ra trước đó. Đảm bảo bạn sử dụng các bộ lọc để chỉ chọn các giao dịch bạn cần. Nếu không, bạn sẽ kết thúc với tấn dữ liệu rất nhanh.

Theo dõi máy chủ SQL - phù hợp nhất nếu bạn muốn nắm bắt tất cả hoặc hầu hết các lệnh và giữ chúng trong tệp theo dõi có thể được phân tích cú pháp sau này.

Kích hoạt - phù hợp nhất nếu bạn muốn chụp DML (ngoại trừ chọn) và lưu trữ chúng ở đâu đó trong cơ sở dữ liệu


Tạo một tệp theo dõi trong SQL Server Profiler ( msdn.microsoft.com/en-us/l Library / ms175047 ( v = sql.110 ) .aspx ) bằng cách sử dụng Mẫu tiêu chuẩn là một cách tốt để theo dõi các câu lệnh đã thực hiện.
javiniar.leonard


6

Như những người khác đã lưu ý, bạn có thể sử dụng SQL Profiler, nhưng bạn cũng có thể tận dụng chức năng của nó thông qua các thủ tục lưu trữ hệ thống sp_trace_ *. Ví dụ: đoạn mã SQL này sẽ (ít nhất là vào năm 2000; tôi nghĩ nó giống với SQL 2008 nhưng bạn sẽ phải kiểm tra kỹ) các sự kiện RPC:CompletedSQL:BatchCompletedsự kiện cho tất cả các truy vấn mất hơn 10 giây để chạy và lưu kết quả đầu ra vào một dấu vết mà bạn có thể mở trong hồ sơ SQL vào một ngày sau:

DECLARE @TraceID INT
DECLARE @ON BIT
DECLARE @RetVal INT
SET @ON = 1

exec @RetVal = sp_trace_create @TraceID OUTPUT, 2, N'Y:\TraceFile.trc'
print 'This trace is Trace ID = ' + CAST(@TraceID AS NVARCHAR)
print 'Return value = ' + CAST(@RetVal AS NVARCHAR)
-- 10 = RPC:Completed
exec sp_trace_setevent @TraceID, 10, 1, @ON     -- Textdata
exec sp_trace_setevent @TraceID, 10, 3, @ON     -- DatabaseID
exec sp_trace_setevent @TraceID, 10, 12, @ON        -- SPID
exec sp_trace_setevent @TraceID, 10, 13, @ON        -- Duration
exec sp_trace_setevent @TraceID, 10, 14, @ON        -- StartTime
exec sp_trace_setevent @TraceID, 10, 15, @ON        -- EndTime

-- 12 = SQL:BatchCompleted
exec sp_trace_setevent @TraceID, 12, 1, @ON     -- Textdata
exec sp_trace_setevent @TraceID, 12, 3, @ON     -- DatabaseID
exec sp_trace_setevent @TraceID, 12, 12, @ON        -- SPID
exec sp_trace_setevent @TraceID, 12, 13, @ON        -- Duration
exec sp_trace_setevent @TraceID, 12, 14, @ON        -- StartTime
exec sp_trace_setevent @TraceID, 12, 15, @ON        -- EndTime

-- Filter for duration [column 13] greater than [operation 2] 10 seconds (= 10,000ms)
declare @duration bigint
set @duration = 10000
exec sp_trace_setfilter @TraceID, 13, 0, 2, @duration

Bạn có thể tìm ID cho từng dấu vết - sự kiện, cột, v.v. từ Sách trực tuyến; chỉ cần tìm kiếm sp_trace_create , sp_trace_seteventsp_trace_setfiler sprocs. Sau đó, bạn có thể kiểm soát dấu vết như sau:

exec sp_trace_setstatus 15, 0       -- Stop the trace
exec sp_trace_setstatus 15, 1       -- Start the trace
exec sp_trace_setstatus 15, 2       -- Close the trace file and delete the trace settings

... Trong đó '15' là ID theo dõi (như được báo cáo bởi sp_trace_create, tập lệnh đầu tiên khởi động, ở trên).

Bạn có thể kiểm tra xem dấu vết nào đang chạy với:

select * from ::fn_trace_getinfo(default)

Điều duy nhất tôi sẽ nói một cách thận trọng - Tôi không biết điều này sẽ tải bao nhiêu cho hệ thống của bạn; nó sẽ thêm một số, nhưng "số" đó lớn đến mức nào có thể phụ thuộc vào mức độ bận rộn của máy chủ của bạn.


Mã hữu ích. Nó chỉ hoạt động với tôi khi tôi gỡ bỏ phần mở rộng tệp ".trc".
Steve Smith

5

Hệ thống không ghi lại các truy vấn theo cách đó. Nếu bạn biết rằng bạn muốn làm điều đó trước thời hạn, bạn có thể sử dụng SQL Profiler để ghi lại những gì đang đến và theo dõi các truy vấn trong thời gian Profiler đang chạy.


5

Tôi sử dụng truy vấn dưới đây để theo dõi hoạt động ứng dụng trên máy chủ SQL không kích hoạt trình hồ sơ theo dõi. Phương pháp sử dụng Kho lưu trữ truy vấn (SQL Server 2016+) thay vì DMV. Điều này cho khả năng tốt hơn để xem xét dữ liệu lịch sử, cũng như tra cứu nhanh hơn. Sẽ rất hiệu quả khi nắm bắt các truy vấn chạy ngắn mà sp_who / sp_whoisactive không thể nắm bắt được.

/* Adjust script to your needs.
    Run full script (F5) -> Interact with UI -> Run full script again (F5)
    Output will contain the queries completed in that timeframe.
*/

/* Requires Query Store to be enabled:
    ALTER DATABASE <db> SET QUERY_STORE = ON
    ALTER DATABASE <db> SET QUERY_STORE (OPERATION_MODE = READ_WRITE, MAX_STORAGE_SIZE_MB = 100000)
*/

USE <db> /* Select your DB */

IF OBJECT_ID('tempdb..#lastendtime') IS NULL
    SELECT GETUTCDATE() AS dt INTO #lastendtime
ELSE IF NOT EXISTS (SELECT * FROM #lastendtime)
    INSERT INTO #lastendtime VALUES (GETUTCDATE()) 

;WITH T AS (
SELECT 
    DB_NAME() AS DBName
    , s.name + '.' + o.name AS ObjectName
    , qt.query_sql_text
    , rs.runtime_stats_id
    , p.query_id
    , p.plan_id
    , CAST(p.last_execution_time AS DATETIME) AS last_execution_time
    , CASE WHEN p.last_execution_time > #lastendtime.dt THEN 'X' ELSE '' END AS New
    , CAST(rs.last_duration / 1.0e6 AS DECIMAL(9,3)) last_duration_s
    , rs.count_executions
    , rs.last_rowcount
    , rs.last_logical_io_reads
    , rs.last_physical_io_reads
    , q.query_parameterization_type_desc
FROM (
    SELECT *, ROW_NUMBER() OVER (PARTITION BY plan_id, runtime_stats_id ORDER BY runtime_stats_id DESC) AS recent_stats_in_current_priod
    FROM sys.query_store_runtime_stats 
    ) AS rs
INNER JOIN sys.query_store_runtime_stats_interval AS rsi ON rsi.runtime_stats_interval_id = rs.runtime_stats_interval_id
INNER JOIN sys.query_store_plan AS p ON p.plan_id = rs.plan_id
INNER JOIN sys.query_store_query AS q ON q.query_id = p.query_id
INNER JOIN sys.query_store_query_text AS qt ON qt.query_text_id = q.query_text_id
LEFT OUTER JOIN sys.objects AS o ON o.object_id = q.object_id
LEFT OUTER JOIN sys.schemas AS s ON s.schema_id = o.schema_id
CROSS APPLY #lastendtime
WHERE rsi.start_time <= GETUTCDATE() AND GETUTCDATE() < rsi.end_time
    AND recent_stats_in_current_priod = 1
    /* Adjust your filters: */
    -- AND (s.name IN ('<myschema>') OR s.name IS NULL)
UNION
SELECT NULL,NULL,NULL,NULL,NULL,NULL,dt,NULL,NULL,NULL,NULL,NULL,NULL, NULL
FROM #lastendtime
)
SELECT * FROM T
WHERE T.query_sql_text IS NULL OR T.query_sql_text NOT LIKE '%#lastendtime%' -- do not show myself
ORDER BY last_execution_time DESC

TRUNCATE TABLE #lastendtime
INSERT INTO #lastendtime VALUES (GETUTCDATE()) 

4
SELECT deqs.last_execution_time AS [Time], dest.text AS [Query], dest.*
FROM sys.dm_exec_query_stats AS deqs
CROSS APPLY sys.dm_exec_sql_text(deqs.sql_handle) AS dest
WHERE dest.dbid = DB_ID('msdb')
ORDER BY deqs.last_execution_time DESC

Điều này sẽ cho bạn thấy thời gian và ngày khi một truy vấn được chạy



2

Lịch sử truy vấn có thể được xem bằng cách sử dụng các chế độ xem hệ thống:

  1. sys.dm_exec_query_stats
  2. sys.dm_exec_sql bản
  3. sys.dm_exec_query_plan

Ví dụ: sử dụng truy vấn sau:

select  top(100)
        creation_time,
        last_execution_time,
        execution_count,
        total_worker_time/1000 as CPU,
        convert(money, (total_worker_time))/(execution_count*1000)as [AvgCPUTime],
        qs.total_elapsed_time/1000 as TotDuration,
        convert(money, (qs.total_elapsed_time))/(execution_count*1000)as [AvgDur],
        total_logical_reads as [Reads],
        total_logical_writes as [Writes],
        total_logical_reads+total_logical_writes as [AggIO],
        convert(money, (total_logical_reads+total_logical_writes)/(execution_count + 0.0)) as [AvgIO],
        [sql_handle],
        plan_handle,
        statement_start_offset,
        statement_end_offset,
        plan_generation_num,
        total_physical_reads,
        convert(money, total_physical_reads/(execution_count + 0.0)) as [AvgIOPhysicalReads],
        convert(money, total_logical_reads/(execution_count + 0.0)) as [AvgIOLogicalReads],
        convert(money, total_logical_writes/(execution_count + 0.0)) as [AvgIOLogicalWrites],
        query_hash,
        query_plan_hash,
        total_rows,
        convert(money, total_rows/(execution_count + 0.0)) as [AvgRows],
        total_dop,
        convert(money, total_dop/(execution_count + 0.0)) as [AvgDop],
        total_grant_kb,
        convert(money, total_grant_kb/(execution_count + 0.0)) as [AvgGrantKb],
        total_used_grant_kb,
        convert(money, total_used_grant_kb/(execution_count + 0.0)) as [AvgUsedGrantKb],
        total_ideal_grant_kb,
        convert(money, total_ideal_grant_kb/(execution_count + 0.0)) as [AvgIdealGrantKb],
        total_reserved_threads,
        convert(money, total_reserved_threads/(execution_count + 0.0)) as [AvgReservedThreads],
        total_used_threads,
        convert(money, total_used_threads/(execution_count + 0.0)) as [AvgUsedThreads],
        case 
            when sql_handle IS NULL then ' '
            else(substring(st.text,(qs.statement_start_offset+2)/2,(
                case
                    when qs.statement_end_offset =-1 then len(convert(nvarchar(MAX),st.text))*2      
                    else qs.statement_end_offset    
                end - qs.statement_start_offset)/2  ))
        end as query_text,
        db_name(st.dbid) as database_name,
        object_schema_name(st.objectid, st.dbid)+'.'+object_name(st.objectid, st.dbid) as [object_name],
        sp.[query_plan]
from sys.dm_exec_query_stats as qs with(readuncommitted)
cross apply sys.dm_exec_sql_text(qs.[sql_handle]) as st
cross apply sys.dm_exec_query_plan(qs.[plan_handle]) as sp
WHERE st.[text] LIKE '%query%'

Các truy vấn đang chạy hiện tại có thể được nhìn thấy bằng cách sử dụng tập lệnh sau:

select ES.[session_id]
      ,ER.[blocking_session_id]
      ,ER.[request_id]
      ,ER.[start_time]
      ,DateDiff(second, ER.[start_time], GetDate()) as [date_diffSec]
      , COALESCE(
                    CAST(NULLIF(ER.[total_elapsed_time] / 1000, 0) as BIGINT)
                   ,CASE WHEN (ES.[status] <> 'running' and isnull(ER.[status], '')  <> 'running') 
                            THEN  DATEDIFF(ss,0,getdate() - nullif(ES.[last_request_end_time], '1900-01-01T00:00:00.000'))
                    END
                ) as [total_time, sec]
      , CAST(NULLIF((CAST(ER.[total_elapsed_time] as BIGINT) - CAST(ER.[wait_time] AS BIGINT)) / 1000, 0 ) as bigint) as [work_time, sec]
      , CASE WHEN (ER.[status] <> 'running' AND ISNULL(ER.[status],'') <> 'running') 
                THEN  DATEDIFF(ss,0,getdate() - nullif(ES.[last_request_end_time], '1900-01-01T00:00:00.000'))
        END as [sleep_time, sec] --Время сна в сек
      , NULLIF( CAST((ER.[logical_reads] + ER.[writes]) * 8 / 1024 as numeric(38,2)), 0) as [IO, MB]
      , CASE  ER.transaction_isolation_level
        WHEN 0 THEN 'Unspecified'
        WHEN 1 THEN 'ReadUncommited'
        WHEN 2 THEN 'ReadCommited'
        WHEN 3 THEN 'Repetable'
        WHEN 4 THEN 'Serializable'
        WHEN 5 THEN 'Snapshot'
        END as [transaction_isolation_level_desc]
      ,ER.[status]
      ,ES.[status] as [status_session]
      ,ER.[command]
      ,ER.[percent_complete]
      ,DB_Name(coalesce(ER.[database_id], ES.[database_id])) as [DBName]
      , SUBSTRING(
                    (select top(1) [text] from sys.dm_exec_sql_text(ER.[sql_handle]))
                  , ER.[statement_start_offset]/2+1
                  , (
                        CASE WHEN ((ER.[statement_start_offset]<0) OR (ER.[statement_end_offset]<0))
                                THEN DATALENGTH ((select top(1) [text] from sys.dm_exec_sql_text(ER.[sql_handle])))
                             ELSE ER.[statement_end_offset]
                        END
                        - ER.[statement_start_offset]
                    )/2 +1
                 ) as [CURRENT_REQUEST]
      ,(select top(1) [text] from sys.dm_exec_sql_text(ER.[sql_handle])) as [TSQL]
      ,(select top(1) [objectid] from sys.dm_exec_sql_text(ER.[sql_handle])) as [objectid]
      ,(select top(1) [query_plan] from sys.dm_exec_query_plan(ER.[plan_handle])) as [QueryPlan]
      ,NULL as [event_info]--(select top(1) [event_info] from sys.dm_exec_input_buffer(ES.[session_id], ER.[request_id])) as [event_info]
      ,ER.[wait_type]
      ,ES.[login_time]
      ,ES.[host_name]
      ,ES.[program_name]
      ,cast(ER.[wait_time]/1000 as decimal(18,3)) as [wait_timeSec]
      ,ER.[wait_time]
      ,ER.[last_wait_type]
      ,ER.[wait_resource]
      ,ER.[open_transaction_count]
      ,ER.[open_resultset_count]
      ,ER.[transaction_id]
      ,ER.[context_info]
      ,ER.[estimated_completion_time]
      ,ER.[cpu_time]
      ,ER.[total_elapsed_time]
      ,ER.[scheduler_id]
      ,ER.[task_address]
      ,ER.[reads]
      ,ER.[writes]
      ,ER.[logical_reads]
      ,ER.[text_size]
      ,ER.[language]
      ,ER.[date_format]
      ,ER.[date_first]
      ,ER.[quoted_identifier]
      ,ER.[arithabort]
      ,ER.[ansi_null_dflt_on]
      ,ER.[ansi_defaults]
      ,ER.[ansi_warnings]
      ,ER.[ansi_padding]
      ,ER.[ansi_nulls]
      ,ER.[concat_null_yields_null]
      ,ER.[transaction_isolation_level]
      ,ER.[lock_timeout]
      ,ER.[deadlock_priority]
      ,ER.[row_count]
      ,ER.[prev_error]
      ,ER.[nest_level]
      ,ER.[granted_query_memory]
      ,ER.[executing_managed_code]
      ,ER.[group_id]
      ,ER.[query_hash]
      ,ER.[query_plan_hash]
      ,EC.[most_recent_session_id]
      ,EC.[connect_time]
      ,EC.[net_transport]
      ,EC.[protocol_type]
      ,EC.[protocol_version]
      ,EC.[endpoint_id]
      ,EC.[encrypt_option]
      ,EC.[auth_scheme]
      ,EC.[node_affinity]
      ,EC.[num_reads]
      ,EC.[num_writes]
      ,EC.[last_read]
      ,EC.[last_write]
      ,EC.[net_packet_size]
      ,EC.[client_net_address]
      ,EC.[client_tcp_port]
      ,EC.[local_net_address]
      ,EC.[local_tcp_port]
      ,EC.[parent_connection_id]
      ,EC.[most_recent_sql_handle]
      ,ES.[host_process_id]
      ,ES.[client_version]
      ,ES.[client_interface_name]
      ,ES.[security_id]
      ,ES.[login_name]
      ,ES.[nt_domain]
      ,ES.[nt_user_name]
      ,ES.[memory_usage]
      ,ES.[total_scheduled_time]
      ,ES.[last_request_start_time]
      ,ES.[last_request_end_time]
      ,ES.[is_user_process]
      ,ES.[original_security_id]
      ,ES.[original_login_name]
      ,ES.[last_successful_logon]
      ,ES.[last_unsuccessful_logon]
      ,ES.[unsuccessful_logons]
      ,ES.[authenticating_database_id]
      ,ER.[sql_handle]
      ,ER.[statement_start_offset]
      ,ER.[statement_end_offset]
      ,ER.[plan_handle]
      ,NULL as [dop]--ER.[dop]
      ,coalesce(ER.[database_id], ES.[database_id]) as [database_id]
      ,ER.[user_id]
      ,ER.[connection_id]
from sys.dm_exec_requests ER with(readuncommitted)
right join sys.dm_exec_sessions ES with(readuncommitted)
on ES.session_id = ER.session_id 
left join sys.dm_exec_connections EC  with(readuncommitted)
on EC.session_id = ES.session_id
where ER.[status] in ('suspended', 'running', 'runnable')
or exists (select top(1) 1 from sys.dm_exec_requests as ER0 where ER0.[blocking_session_id]=ES.[session_id])

Yêu cầu này hiển thị tất cả các yêu cầu hoạt động và tất cả các yêu cầu đó rõ ràng chặn các yêu cầu hoạt động.

Tất cả các tập lệnh này và các tập lệnh hữu ích khác được triển khai dưới dạng biểu diễn trong cơ sở dữ liệu SRV , được phân phối tự do. Ví dụ: tập lệnh đầu tiên xuất phát từ chế độ xem [inf]. [BBigQuery] và tập lệnh thứ hai đến từ chế độ xem [inf]. [VRequests] .

Ngoài ra còn có các giải pháp bên thứ ba khác nhau cho lịch sử truy vấn. Tôi sử dụng Trình quản lý truy vấn từ Dbeaver : nhập mô tả hình ảnh ở đâyLịch sử thực hiện truy vấn từ các công cụ SQL , được nhúng trong SSMS : nhập mô tả hình ảnh ở đây


1

Tính năng này không tồn tại ngoài hộp trong SSMS.

Nếu bạn đang sử dụng SSMS 18 hoặc mới hơn, bạn có thể muốn thử SSMSPlus.

Nó có một tính năng lịch sử truy vấn.

https://github.com/akarzazi/SSMSPlus

Tuyên bố miễn trừ trách nhiệm: Tôi là tác giả.


0

bạn có thể sử dụng "Tự động tạo tập lệnh trên mỗi lần lưu", nếu bạn đang sử dụng phòng quản lý. Điều này không chắc chắn đăng nhập. Kiểm tra nếu hữu ích cho bạn ..;)


0

Nếu các truy vấn bạn quan tâm là các truy vấn động không liên tục, bạn có thể đăng nhập SQL và datetime và user trong một bảng tại thời điểm câu lệnh động được tạo. Nó sẽ được thực hiện trong từng trường hợp cụ thể vì nó đòi hỏi phải lập trình cụ thể và phải mất thêm một ít thời gian xử lý, do đó, chỉ thực hiện cho một vài truy vấn mà bạn quan tâm nhất. Nhưng có một bản ghi các câu lệnh cụ thể được thực thi có thể thực sự có ích khi bạn đang cố gắng tìm hiểu tại sao nó chỉ thất bại mỗi tháng một lần. Các truy vấn động rất khó kiểm tra kỹ lưỡng và đôi khi bạn nhận được một giá trị đầu vào cụ thể sẽ không hoạt động và thực hiện việc ghi nhật ký này tại thời điểm SQL được tạo thường là cách tốt nhất để xem cụ thể là gì trong sql được xây dựng.


0

Một phương pháp hơi khó hiểu sẽ là kịch bản hóa một giải pháp trong AutoHotKey. Tôi sử dụng cái này, và nó không hoàn hảo, nhưng hoạt động và miễn phí. Về cơ bản, tập lệnh này gán một phím nóng cho CTRL+ SHIFT+ Rsẽ sao chép SQL đã chọn trong SSMS ( CTRL+ C), lưu tệp SQL dấu thời gian và sau đó thực hiện truy vấn được tô sáng ( F5). Nếu bạn không quen sử dụng tập lệnh AHK, dấu chấm phẩy hàng đầu là một nhận xét.

;CTRL+SHIFT+R to run a query that is first saved off
^+r::
;Copy
Send, ^c
; Set variables
EnvGet, HomeDir, USERPROFILE
FormatTime, DateString,,yyyyMMdd
FormatTime, TimeString,,hhmmss
; Make a spot to save the clipboard
FileCreateDir %HomeDir%\Documents\sqlhist\%DateString%
FileAppend, %Clipboard%, %HomeDir%\Documents\sqlhist\%DateString%\%TimeString%.sql
; execute the query
Send, {f5}
Return

Hạn chế lớn nhất là tập lệnh này sẽ không hoạt động nếu bạn nhấp vào "Thực thi" thay vì sử dụng phím tắt và tập lệnh này sẽ không lưu toàn bộ tệp - chỉ văn bản đã chọn. Nhưng, bạn luôn có thể sửa đổi tập lệnh để thực hiện truy vấn và sau đó chọn tất cả ( CTRL+ A) trước khi sao chép / lưu.

Sử dụng trình soạn thảo hiện đại với các tính năng "tìm trong tệp" sẽ cho phép bạn tìm kiếm lịch sử SQL của mình. Bạn thậm chí có thể nhận được ưa thích và cạo các tệp của bạn vào cơ sở dữ liệu SQLite3 để truy vấn các truy vấn của bạn.

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.