Han*_*non 7 sql-server-2005 sql-server dynamic-sql
我正在编写一些动态 SQL 来识别,也许如果我觉得够疯狂,可以自动将我的NONCLUSTERED索引转换为CLUSTERED索引。
ORDER BY 1,2,3 DESC;下面的 SQL 中的这一行旨在在DROP INDEX...语句之前输出语句ALTER TABLE...,以便先删除 NONCLUSTERED 索引,然后添加一个 CLUSTERED 索引。我必须在第DESC3 列之后添加DROP,然后是 ALTER。这是倒退,除非我失去它!
DECLARE @Server nvarchar(max);
DECLARE @Database nvarchar(max);
DECLARE @cmd nvarchar(max);
DECLARE @IndexType int;
SET @IndexType = 2; /* 1 is CLUSTERED, 2 is NONCLUSTERED */
SET @Server = 'MyServer';
SET @Database = 'MyDatabase';
SET @cmd = '
DECLARE @cmd nvarchar(max);
SET @cmd = ''
SET NOCOUNT ON;
DECLARE @IndexInfo TABLE (TableName nvarchar(255), IndexName nvarchar(255), IndexColumnName nvarchar(255));
INSERT INTO @IndexInfo (TableName, IndexName, IndexColumnName)
SELECT t.name AS TableName, i.name AS IndexName, c.name AS IndexColumnName /*, t.create_date, ic.*, c.* */
FROM sys.tables t
LEFT JOIN sys.indexes i ON t.object_id = i.object_id
LEFT JOIN sys.index_columns ic ON i.object_id = ic.object_id AND i.index_id = ic.index_id
LEFT JOIN sys.columns c ON i.object_id = c.object_id and ic.column_id = c.column_id
WHERE i.is_primary_key = 1
AND i.type = ' + CAST(@IndexType as nvarchar(max)) + '
ORDER BY t.create_date desc;
DECLARE @t1 nvarchar(max);
DECLARE @t2 nvarchar(max);
DECLARE @t3 nvarchar(max);
DECLARE @cmd nvarchar(max);
DECLARE cur CURSOR FOR
SELECT TableName, IndexName, 1 AS ExecOrder, ''''DROP INDEX '''' + IndexName + '''' ON '''' + TableName + '''';'''' FROM @IndexInfo I
UNION ALL
SELECT TableName, IndexName, 2 AS ExecOrder, ''''ALTER TABLE '''' + TableName + '''' ADD CONSTRAINT PK_'''' + TableName + ''''_'''' + IndexColumnName + '''' PRIMARY KEY CLUSTERED ('''' + IndexColumnName + '''')'''' + '''';'''' FROM @IndexInfo I
ORDER BY 1,2,3 DESC;
OPEN cur;
FETCH NEXT FROM cur INTO @t1, @t2, @t3, @cmd;
WHILE @@FETCH_STATUS = 0
BEGIN
PRINT @cmd;
FETCH NEXT FROM cur INTO @t1, @t2, @t3, @cmd;
END
CLOSE cur;
DEALLOCATE cur;
'';
EXEC ' + @Server + '.' + @Database + '.sys.sp_executesql @cmd;
';
PRINT @cmd;
Run Code Online (Sandbox Code Playgroud)
Pau*_*ite 11
该PRINT内部声明WHILE循环不执行你所期望的顺序,但在此之前的输出缓冲sys.sp_executesql的回报。实现细节意味着缓冲输出被反转。
使用RAISERROR (@cmd, 0, 1) WITH NOWAIT;而不是PRINT强制缓冲区在每次调用后刷新,按照您期望的顺序为您提供结果。IIRC 该NOWAIT技巧仅适用于前 500 行的每行。在任何情况下,所有这些都是无证的东西,随时可能改变,所以请不要依赖它——我提到它只是为了解释你所看到的。
如果您将sp_executesql调用替换为EXEC (@cmd) AT ' + @Server + '虽然确实需要USE database前缀为的命令@cmd并且链接服务器需要为 RPC 启用,则不会发生逆转。这也不是建议,只是显示输出反转是sp_executesql.
鉴于评论中列出的新信息,至少有三种解决方案不需要动态 SQL 和手动操作,事后反应:
说真的,他是一名 DBA,负责贵公司的工作。当然,您可以实施一项策略,即表具有聚集索引,除非在某些情况下(在这种情况下,它们必须被注销)。当作为政策表述时,这将成为衡量工作绩效的潜在可量化衡量标准。
CREATE_TABLE在 DDL 触发器中捕获事件非常容易,然后检查 sys.indexes 或 sys.partitions 目录视图是否存在聚集索引。没有聚集索引?回滚。这将消除 的可能性SELECT INTO,因为您不能提前定义聚集索引,但也许没关系。
如果没有聚集索引,就无法在云中创建表。如果您让他在那里发展,则不需要标尺或 DDL 触发器。
你为什么使用序数?代替:
ORDER BY 1,2,3 DESC;
Run Code Online (Sandbox Code Playgroud)
尝试直接引用别名:
ORDER BY TableName, IndexName, ExecOrder;
Run Code Online (Sandbox Code Playgroud)
你也使用游标来建立@cmd,我希望你能在某个地方附加它。目前看来,您正在遍历游标,但只@cmd从循环中的最后一次迭代开始执行。那么游标的目的是什么?如果确实需要光标,为什么不使用更好的光标选项?(如果不是,您可以将其更改为单个 TOP 查询)。
| 归档时间: |
|
| 查看次数: |
1301 次 |
| 最近记录: |