Cara melihat riwayat kueri di SQL Server Management Studio

159

Apakah riwayat kueri disimpan dalam beberapa file log? Jika ya, dapatkah Anda memberi tahu saya cara menemukan lokasi mereka? Jika tidak, bisakah Anda memberi saya saran tentang cara melihatnya?

mstaniloiu
sumber
1
http://www.ssmstoolspack.com/ memberikan jendela riwayat jika itu yang Anda cari.
TI

Jawaban:

226

[Karena pertanyaan ini kemungkinan akan ditutup sebagai duplikat.]

Jika SQL Server belum dimulai ulang (dan paketnya belum digusur, dll.), Anda mungkin dapat menemukan kueri dalam cache paket.

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%';

Jika Anda kehilangan file karena Management Studio macet, Anda mungkin dapat menemukan file pemulihan di sini:

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

Kalau tidak, Anda harus menggunakan sesuatu yang lain untuk membantu Anda menyimpan riwayat kueri Anda, seperti SSMS Tools Pack seperti yang disebutkan dalam jawaban Ed Harper - meskipun tidak gratis di SQL Server 2012+. Atau Anda dapat mengatur beberapa pelacakan ringan yang difilter pada login atau nama host Anda (tapi tolong gunakan jejak sisi server, bukan Profiler, untuk ini).


Seperti yang dikomentari @ Nenad-Zivkovic, mungkin akan membantu untuk bergabung sys.dm_exec_query_statsdan memesan dengan 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;
Aaron Bertrand
sumber
9
Juga dapat membantu untuk bergabung sys.dm_exec_query_statsdan mencari atau memesan olehlast_execution_time
Nenad Zivkovic
Tidak berfungsi dengan sql server 2000 dan bekerja dari sql server 2005
Durai Amuthan.H
@Duraiamuthan Nah, pertanyaannya tentang Management Studio, jadi seharusnya aman untuk menganggap 2005+. 2000 tidak memiliki Management Studio, itu punya Query Analyzer. 2000 juga bertahun-tahun di luar dukungan. Jika Anda ingin menyelesaikan masalah ini untuk SQL Server 2000, Anda mungkin harus mengajukan pertanyaan baru yang ditandai dengan versi tertentu (jika tidak ada duplikat, yang saya tidak periksa).
Aaron Bertrand
1
@AaronBertrand Komentar saya adalah tambahan untuk jawaban Anda. Itu akan membantu orang lain
Durai Amuthan.H
3
@ AaronBertrand Anda adalah dewa di antara para pria.
AnotherDeveloper
49

Terlambat tapi semoga bermanfaat karena menambah detail ...

Tidak ada cara untuk melihat kueri dieksekusi di SSMS secara default. Ada beberapa opsi.

Membaca log transaksi - ini bukan hal yang mudah dilakukan karena ini dalam format berpemilik. Namun jika Anda perlu melihat kueri yang dieksekusi secara historis (kecuali SELECT) ini adalah satu-satunya cara.

Anda dapat menggunakan alat pihak ketiga untuk ini seperti ApexSQL Log dan SQL Log Rescue (gratis tetapi hanya SQL 2000). Lihat utas ini untuk lebih jelasnya di sini SQL Server Transaction Log Explorer / Analyzer

Profiler SQL Server - paling cocok jika Anda hanya ingin memulai audit dan Anda tidak tertarik dengan apa yang terjadi sebelumnya. Pastikan Anda menggunakan filter untuk memilih hanya transaksi yang Anda butuhkan. Kalau tidak, Anda akan berakhir dengan banyak data dengan sangat cepat.

Jejak SQL Server - paling cocok jika Anda ingin menangkap semua atau sebagian besar perintah dan menyimpannya dalam file jejak yang dapat diuraikan kemudian.

Pemicu - paling cocok jika Anda ingin menangkap DML (kecuali pilih) dan menyimpannya di suatu tempat dalam database

Djordje Kujundzic
sumber
Membuat File Jejak di SQL Server Profiler ( msdn.microsoft.com/en-us/library/ms175047(v=sql.110).aspx ) menggunakan Template Standar adalah cara yang baik untuk memantau pernyataan yang dijalankan.
javiniar.leonard
16

Paket alat SSMS menambah fungsionalitas untuk mencatat riwayat eksekusi, di antara hal-hal lainnya.

Ed Harper
sumber
22
Tidak lagi gratis pada SSMS 2012.
mattmc3
6

Seperti yang telah dicatat orang lain, Anda dapat menggunakan SQL Profiler, tetapi Anda juga dapat memanfaatkan fungsinya melalui prosedur tersimpan sistem sp_trace_ *. Sebagai contoh, potongan SQL ini akan (setidaknya pada 2000; saya pikir itu sama untuk SQL 2008 tetapi Anda harus memeriksa ulang) menangkap RPC:Completeddan SQL:BatchCompletedperistiwa untuk semua kueri yang membutuhkan waktu lebih dari 10 detik untuk berjalan, dan menyimpan output ke sebuah jejak yang dapat Anda buka di profiler SQL di kemudian hari:

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

Anda dapat menemukan ID untuk setiap jejak-peristiwa, kolom, dll dari Books Online; cukup cari sp_trace_create , sp_trace_setevent dan sp_trace_setfiler sprocs. Anda kemudian dapat mengontrol jejak sebagai berikut:

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

... di mana '15' adalah jejak ID (seperti yang dilaporkan oleh sp_trace_create, yang skrip pertama usai, di atas).

Anda dapat memeriksa untuk melihat jejak apa yang sedang berjalan:

select * from ::fn_trace_getinfo(default)

Satu-satunya hal yang akan saya katakan dengan hati - hati - saya tidak tahu berapa banyak beban ini akan dimasukkan ke sistem Anda; itu akan menambahkan beberapa, tetapi seberapa besar "beberapa" itu mungkin tergantung seberapa sibuk server Anda.

Chris J
sumber
Kode yang bermanfaat Itu hanya bekerja untuk saya ketika saya menghapus ekstensi file ".trc".
Steve Smith
5

Sistem tidak mencatat kueri dengan cara itu. Jika Anda tahu Anda ingin melakukan itu sebelumnya, Anda dapat menggunakan SQL Profiler untuk mencatat apa yang masuk dan melacak permintaan selama waktu Profiler berjalan.

Tiamin
sumber
5

Saya menggunakan kueri di bawah ini untuk melacak aktivitas aplikasi pada server SQL yang tidak memiliki profiler jejak diaktifkan. Metode ini menggunakan Query Store (SQL Server 2016+) bukan DMV. Ini memberikan kemampuan yang lebih baik untuk melihat data historis, serta pencarian yang lebih cepat. Sangat efisien untuk menangkap kueri berjalan pendek yang tidak dapat ditangkap oleh sp_who / sp_whoisactive.

/* 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()) 
Martin Thøgersen
sumber
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

Ini akan menunjukkan kepada Anda waktu dan tanggal ketika kueri dijalankan

Jose Ortiz
sumber
3

Anda dapat Memantau kueri SQL oleh SQL Profiler jika Anda membutuhkannya

Arsen Mkrtchyan
sumber
3

Riwayat kueri dapat dilihat menggunakan tampilan sistem:

  1. sys.dm_exec_query_stats
  2. sys.dm_exec_sql_text
  3. sys.dm_exec_query_plan

Misalnya, menggunakan kueri berikut:

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%'

Permintaan berjalan saat ini dapat dilihat menggunakan skrip berikut:

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])

Permintaan ini menampilkan semua permintaan aktif dan semua permintaan yang secara eksplisit memblokir permintaan aktif.

Semua ini dan skrip berguna lainnya diimplementasikan sebagai representasi dalam database SRV , yang didistribusikan secara bebas. Misalnya, skrip pertama berasal dari tampilan [inf]. [VBigQuery] , dan yang kedua berasal dari tampilan [inf]. [VRequests] .

Ada juga berbagai solusi pihak ketiga untuk riwayat kueri. Saya menggunakan Manajer Kueri dari Dbeaver : masukkan deskripsi gambar di sini dan Riwayat Eksekusi Kueri dari SQL Tools , yang tertanam dalam SSMS : masukkan deskripsi gambar di sini

Evgeniy Gribkov
sumber
1

Fitur ini tidak ada di luar kotak di SSMS.

Jika Anda menggunakan SSMS 18 atau yang lebih baru, Anda mungkin ingin mencoba SSMSPlus.

Ini memiliki fitur riwayat permintaan.

https://github.com/akarzazi/SSMSPlus

Penafian: Saya penulis.

Adelos
sumber
0

Anda dapat menggunakan "Secara otomatis menghasilkan skrip di setiap save", jika Anda menggunakan studio manajemen. Ini belum tentu masuk. Periksa apakah bermanfaat untuk Anda ..;)

Dosa
sumber
0

Jika kueri yang Anda minati adalah kueri dinamis yang gagal sebentar-sebentar, Anda bisa mencatat SQL dan datetime dan pengguna dalam tabel pada saat pernyataan dinamis dibuat. Ini akan dilakukan berdasarkan kasus per kasus meskipun karena memerlukan pemrograman khusus untuk terjadi dan itu membutuhkan waktu pemrosesan ekstra kecil, jadi lakukan hanya untuk beberapa pertanyaan yang paling Anda khawatirkan. Tetapi memiliki log pernyataan spesifik dieksekusi dapat sangat membantu ketika Anda mencoba mencari tahu mengapa itu gagal sebulan sekali saja. Kueri dinamis sulit untuk diuji secara menyeluruh dan kadang-kadang Anda mendapatkan satu nilai input spesifik yang tidak akan berfungsi dan melakukan pencatatan ini pada saat SQL dibuat seringkali merupakan cara terbaik untuk melihat apa yang secara khusus tidak ada dalam sql yang dibangun.

HLGEM
sumber
0

Metode yang sedikit out-of-the-box adalah untuk skrip solusi di AutoHotKey. Saya menggunakan ini, dan itu tidak sempurna, tetapi berfungsi dan gratis. Pada dasarnya, skrip ini memberikan hotkey ke CTRL+ SHIFT+ Ryang akan menyalin SQL yang dipilih dalam SSMS ( CTRL+ C), menyimpan file SQL datestamp, dan kemudian menjalankan kueri yang disorot ( F5). Jika Anda tidak terbiasa dengan skrip AHK, tanda titik koma yang utama adalah komentar.

;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

Batasan terbesar adalah bahwa skrip ini tidak akan berfungsi jika Anda mengklik "Jalankan" daripada menggunakan pintasan keyboard, dan skrip ini tidak akan menyelamatkan seluruh file - hanya teks yang dipilih. Tapi, Anda selalu dapat memodifikasi skrip untuk menjalankan kueri, lalu pilih semua ( CTRL+A ) sebelum menyalin / menyimpan.

Menggunakan editor modern dengan fitur "temukan dalam file" akan memungkinkan Anda mencari riwayat SQL Anda. Anda bahkan bisa mendapatkan mewah dan mengikis file Anda ke dalam database SQLite3 untuk permintaan pertanyaan Anda.

mattmc3
sumber