Mar*_*lli 7 monitoring sql-server ssms t-sql sql-server-2014
我有一些流程需要在开始之前采取不同的步骤。例如:
禁用对外键的检查约束:
select 'alter table '+fk.table_schema+'.'+fk.table_name
+' NOCHECK CONSTRAINT '+fk.CONSTRAINT_NAME
from SAProduct.information_schema.table_constraints fk
join SAProduct.information_schema.tables t
on t.table_schema = fk.table_schema
and t.table_name = fk.table_name
WHERE constraint_type='FOREIGN KEY'
Run Code Online (Sandbox Code Playgroud)
这将产生一个很大的语句列表,我只复制 3 个:
use saproduct
go
alter table dbo.tblProdClassificationCode NOCHECK CONSTRAINT FK_tblProdClassificationCode_tblProdClassification
alter table dbo.tblProdClassificationCodeDescr NOCHECK CONSTRAINT fk_ProdClassificationCodeDescr_ProdClassificationCode
alter table dbo.tblProdClassificationCodeGenerate NOCHECK CONSTRAINT fk_ProdClassificationCodeGenerate_ProdClassification
Run Code Online (Sandbox Code Playgroud)
如果我要一次性运行它,我将如何找到我的位置?我正在处理哪张桌子,下一张是哪一张?
删除也是一样的:
select 'DELETE FROM '+table_schema+'.'+table_name
from saproduct.information_schema.tables
where table_name like 'tbl%'
Run Code Online (Sandbox Code Playgroud)
上面的脚本将生成以下语句集:
use saproduct
go
DELETE FROM dbo.tblBLanguage
DELETE FROM dbo.tblBLgCategoryXRef
DELETE FROM dbo.tblBLgSegmentXRef
DELETE FROM dbo.tblProdClassification
DELETE FROM dbo.tblProdClassificationCode
DELETE FROM dbo.tblProdClassificationCodeDescr
DELETE FROM dbo.tblProdClassificationCodeGenerate
DELETE FROM dbo.tblProdClassificationDescr
DELETE FROM dbo.tblProdClassificationMarket
DELETE FROM dbo.tblProdClassificationTier
DELETE FROM dbo.tblProdClassificationValue
DELETE FROM dbo.tblProdData
DELETE FROM dbo.tblProdDataDescr
DELETE FROM dbo.tblProdDataMarket
DELETE FROM dbo.tblProdDataTempTier1Descr
DELETE FROM dbo.tblProdDataTempTier1Tier2Descr
DELETE FROM dbo.tblProdDataTier
DELETE FROM dbo.tblProdDataValue
DELETE FROM dbo.tblProdDataValueDate
DELETE FROM dbo.tblProdDataValueNumber
DELETE FROM dbo.tblProdDataValueString
DELETE FROM dbo.tblProdName
DELETE FROM dbo.tblProdNameSizeAlias
DELETE FROM dbo.tblProdNameSizeRuleAlias
DELETE FROM dbo.tblProdNameStructure
DELETE FROM dbo.tblProdNameStructureDescr
DELETE FROM dbo.tblProduct
Run Code Online (Sandbox Code Playgroud)
下一张是我要删除的表?
我试图按特定顺序访问表以尽量减少死锁,特别是在必须放置任何类型的排他锁时。它不在这里,但我也尽量避免锁升级,所以它会变得复杂。我喜欢“看到”到底发生了什么。我正在使用 SQL Server 2014:
Microsoft SQL Server 2014 - 12.0.2000.8 (X64)
Feb 20 2014 20:04:26
Copyright (c) Microsoft Corporation
Developer Edition (64-bit) on Windows NT 6.3 <X64> (Build 9600: ) (Hypervisor)
Run Code Online (Sandbox Code Playgroud)
Geo*_*son 12
我同意 Aaron 的观点,这RAISERROR...WITH NOWAIT非常有用,如果您可以完全控制正在生成的脚本,这可能是可行的方法。
但是,如果当前正在执行一个长脚本并且您无法更改脚本以添加RAISERROR调用,那么获取此信息的方法也不太直接。
测试脚本
这是一个测试脚本,您可以运行它来帮助演示以下两种方法:
SELECT 1
WAITFOR DELAY '00:00:15'
SELECT 2
WAITFOR DELAY '00:00:15'
SELECT 3
Run Code Online (Sandbox Code Playgroud)
sp_whosiasctive
运行此脚本时,您可以使用sp_whoisactive查看当前服务器活动。您通常可以查看当前正在执行的特定语句的查询计划。就我而言,我看到以下内容,因为该WAITFOR语句最有可能在任何给定时刻运行:
使用 sys.dm_exec_requests.statement_start_offset
或者,Conor Cunningham 也有一篇关于从AND 中提取语句的帖子。我不相信这已经被纳入,但您可以使用如下查询来查看当前执行的语句和整个批处理。sys.dm_exec_query_statssys.dm_exec_sql_textsp_whoisactive
SELECT er.session_Id AS spid
--Use the full batch text and the start/end offset of the currect statement to figure
--out the SQL that is currently executing. This logic is based on the blog post above
--but has been updated in light of strange cases in SQL Server that caused the original
--blog post logic to crash with out of bounds errors on the SUBSTRING operation.
, SUBSTRING (qt.text
, (CASE WHEN er.statement_start_offset > DATALENGTH(qt.text)
THEN 0 ELSE er.statement_start_offset/2 END)+1
, (CASE WHEN er.statement_end_offset <= 0 THEN DATALENGTH(qt.text)
ELSE er.statement_end_offset
END - CASE WHEN er.statement_start_offset > DATALENGTH(qt.text)
THEN 0 ELSE er.statement_start_offset/2 END)
+ 1
) AS query
, qt.text AS parent_query
FROM sys.dm_exec_requests er
JOIN sys.dm_exec_sessions s
ON s.session_id = er.session_id
AND s.session_id <> @@SPID -- Ignore this current statement.
AND s.is_user_process = 1 -- Ignore system spids.
AND s.program_name NOT LIKE '%SQL Server Profiler%' -- Ignore profiler traces
OUTER APPLY sys.dm_exec_sql_text(er.sql_handle)as qt
ORDER BY spid
Run Code Online (Sandbox Code Playgroud)
这是一种生成脚本的方法,该脚本在一个命令完成时将数据输出到屏幕,并同时宣布下一个命令。重要的是使用RAISERRORwithNOWAIT这样您就不会依赖于 SSMS 中的缓冲区输出管理器来决定何时应该PRINT在消息窗格中看到输出。
DECLARE @sql NVARCHAR(MAX) = N'';
SELECT @sql += N' RAISERROR(''Next is '
+ QUOTENAME(s.name) + N'.'
+ QUOTENAME(t.name) + ''',0,1) WITH NOWAIT;
--DELETE ' + QUOTENAME(s.name) + N'.'
+ QUOTENAME(t.name) + ';
RAISERROR(''Finished '
+ QUOTENAME(s.name) + N'.'
+ QUOTENAME(t.name) + ''',0,1) WITH NOWAIT;'
FROM saproduct.sys.schemas AS s
INNER JOIN saproduct.sys.tables AS t
ON s.[schema_id] = t.[schema_id]
WHERE t.name LIKE N'tbl%';
PRINT @sql;
--EXEC saproduct.sys.sp_executesql @sql;
Run Code Online (Sandbox Code Playgroud)
这将有这样的输出(删除--你想要真正运行它的时候):
RAISERROR('Next is [dbo].[Table1]',0,1) WITH NOWAIT;
--DELETE [dbo].[Table1];
RAISERROR('Finished [dbo].[Table1]',0,1) WITH NOWAIT;
RAISERROR('Next is [dbo].[Table2]',0,1) WITH NOWAIT;
--DELETE [dbo].[Table2];
RAISERROR('Finished [dbo].[Table2]',0,1) WITH NOWAIT;
...
Run Code Online (Sandbox Code Playgroud)
(为什么我使用专有目录视图而不是不完整的INFORMATION_SCHEMA视图。)