【问题标题】:Execute T-SQL Alter Statements created from SELECT statement?执行从 SELECT 语句创建的 T-SQL Alter 语句?
【发布时间】:2021-09-05 08:10:30
【问题描述】:

最终目标:更改 T-SQL 中特定索引的特定选项。

设置:SQL Server Express 安装 / SQL Server Management Studio 19 / 数据库 = AdventureWorks2019

我有以下 SELECT 语句查询我想要更改 row_locking/page_locking 选项的索引

select 'alter index '+ I.name +' on ' + s.name +'.'+ t.name + ' set (allow_row_locks = off, allow_page_locks = off);' 
FROM sys.dm_db_index_physical_stats (DB_ID(), NULL, NULL, NULL, NULL) AS DDIPS
INNER JOIN sys.tables T on T.object_id = DDIPS.object_id
INNER JOIN sys.schemas S on T.schema_id = S.schema_id
INNER JOIN sys.indexes I ON I.object_id = DDIPS.object_id
AND DDIPS.index_id = I.index_id
WHERE DDIPS.database_id = DB_ID()
and I.name is not null
AND DDIPS.avg_fragmentation_in_percent > 0;

这会创建一系列我想要执行的结果。

示例行:

alter index PK_EmployeePayHistory_BusinessEntityID_RateChangeDate on HumanResources.EmployeePayHistory set (allow_row_locks = off, allow_page_locks = off);

据我目前所知,我必须手动从 select 语句中复制结果集,然后将其作为自己的查询执行,我一直在寻找一种方法来将该过程自动化到一个或多个脚本中。

这样可以吗?

【问题讨论】:

  • 您可以将结果提取到游标中,对其进行迭代并使用EXECUTE 或sp_executesql 执行查询。
  • 或者只是将结果粘贴到 SSMS 窗口中并运行代码。
  • 提示:将对象名称组装成动态 SQL 语句时的最佳做法是使用 QuoteName() 以避免出现奇怪名称的问题,例如New Table 带有空格或保留字,例如 From。

标签: sql sql-server tsql dynamic-sql adventureworks


【解决方案1】:

根据用户“sticky bit”的评论 - 我能够使脚本包含 sp_executesql 并迭代 ALTER 命令。

下面是我如何做到这一点的。

USE AdventureWorks2019;
GO

DECLARE @SQLString NVARCHAR(255);
DECLARE Index_Cursor CURSOR FOR
select 'alter index '+ I.name +' on ' + s.name +'.'+ t.name + ' set (allow_row_locks = off, allow_page_locks = off);' 
FROM sys.dm_db_index_physical_stats (DB_ID(), NULL, NULL, NULL, NULL) AS DDIPS
INNER JOIN sys.tables T on T.object_id = DDIPS.object_id
INNER JOIN sys.schemas S on T.schema_id = S.schema_id
INNER JOIN sys.indexes I ON I.object_id = DDIPS.object_id
AND DDIPS.index_id = I.index_id
WHERE DDIPS.database_id = DB_ID()
and I.name is not null
AND DDIPS.avg_fragmentation_in_percent > 0;

OPEN Index_Cursor;

FETCH NEXT FROM Index_Cursor INTO @SQLString;

WHILE @@FETCH_STATUS = 0
BEGIN
    EXECUTE sp_executesql @SQLString;

    FETCH NEXT FROM Index_Cursor INTO @SQLString;
END

CLOSE Index_Cursor;
DEALLOCATE Index_Cursor;
GO

【讨论】:

  • DECLARE @SQLString NVARCHAR(max); 并确保在表和索引引用上使用QUOTENAME。在可能的情况下,通过参数将数据传递到sp_executesql(在本示例中不相关)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-01-28
  • 1970-01-01
  • 1970-01-01
  • 2015-10-23
  • 2014-12-05
  • 2013-10-10
  • 1970-01-01
相关资源
最近更新 更多