Ошибка ALTER INDEX из-за идентификатора QUOTED при запуске из sp msForEachTable
когда я пытаюсь перестроить индекс в таблице:
ALTER INDEX ALL ON [dbo].[Allocations] REBUILD
это прекрасно работает.
но когда я называю
EXECUTE sp_msForEachTable 'ALTER INDEX ALL ON ? REBUILD'
Я достигаю той же самой таблицы, и она терпит неудачу с:
Msg 1934, Уровень 16, Состояние 1, Строка 2
Не удалось изменить индекс, поскольку следующие параметры набора имеют неправильные настройки: 'QUOTED_IDENTIFIER'. Убедитесь, что параметры SET корректны для использования с индексированными представлениями и / или индексами в вычисляемых Столбцах и / или отфильтрованных индексы и/или уведомления о запросах и/или методы типа данных XML и / или операции пространственного индекса.
и подтвердить, что это та же таблица:
EXECUTE sp_msForEachTable 'print ''Rebuilding ?'';
ALTER INDEX ALL ON ? REBUILD;
PRINT '' Done ?'''
что дает результаты:
Rebuilding [dbo].[SystemConfiguration]
Done [dbo].[SystemConfiguration]
Rebuilding [dbo].[UserGroups]
Done [dbo].[UserGroups]
Rebuilding [dbo].[Groups]
Done [dbo].[Groups]
Rebuilding [dbo].[UserPermissions]
Done [dbo].[UserPermissions]
Rebuilding [dbo].[AllocationAdmins]
Done [dbo].[AllocationAdmins]
Rebuilding [dbo].[Allocations]
Msg 1934, Level 16, State 1, Line 2
ALTER INDEX failed because the following SET options have incorrect settings: 'QUOTED_IDENTIFIER'. Verify that SET options are correct for use with indexed views and/or indexes on computed columns and/or filtered indexes and/or query notifications and/or XML data type methods and/or spatial index operations.
что я не так делаю?
Примечание:
EXECUTE sp_msForEachTable 'DBCC DBREINDEX(''?'')'
работает отлично!
3 ответов
параметры идентификатора в кавычках хранятся для каждой хранимой процедуры, и sp_MSforeachtable
он определен как OFF
. Однако вы можете обойти это - установив его в ON
перед выполнением повторного индекса:
create table dbo.T (
ID int not null,
constraint PK_T PRIMARY KEY (ID)
)
go
create view dbo.V ( ID)
with schemabinding
as
select ID from dbo.T
go
create unique clustered index IX_V on dbo.V(ID)
go
ALTER INDEX ALL ON dbo.V REBUILD --Fine
go
exec sp_MSforeachtable 'ALTER INDEX ALL ON ? REBUILD' --Errors
go
exec sp_MSforeachtable 'SET QUOTED_IDENTIFIER ON;
ALTER INDEX ALL ON ? REBUILD' --Fine
при создании хранимой процедуры
SET QUOTED_IDENTIFIER
иSET ANSI_NULLS
настройки фиксируются и используются для последующих вызовов, которые хранятся процедура.
и, конечно же, вставьте обычные предостережения о sp_MSforeachtable
будучи недокументированным, и поэтому вы не можете полагаться на его стабильное поведение.
на DBCC DBREINDEX
- все ставки выключены. DBCC
живет в своем собственном маленьком, очень настроенном мире кода. Но, конечно, и на будущую работу полагаться не стоит:
эта функция будет удалена в будущей версии Microsoft SQL Server. Не используйте эту функцию в новой работе разработки и измените приложения, которые в настоящее время используют эту функцию как можно скорее. Использовать
ALTER INDEX
вместо.
вам нужно SET QUOTED_IDENTIFIER ON
на sp_msForEachTable
, потому что sp_msForEachTable
не имеет права устанавливать.
EXECUTE sp_msForEachTable 'SET QUOTED_IDENTIFIER ON; ALTER INDEX ALL ON ? REBUILD;'
не использовать sp_msforeachtable. Документально подтверждено упустить объект. Вам было бы намного лучше перебирать список таблиц с помощью sys.таблицы.
DECLARE @id INT ,
@table NVARCHAR(256) ,
@reindex NVARCHAR(4000)
SELECT @id = MIN(object_id)
FROM sys.tables
WHILE @id IS NOT NULL
BEGIN
SELECT @table = QUOTENAME(s.name) + '.' + QUOTENAME(t.name)
FROM sys.tables t
INNER JOIN sys.schemas s ON t.schema_id = s.schema_id
WHERE t.object_id = @id
SELECT @reindex = 'SET QUOTED IDENTIFIER ON; ALTER INDEX ALL ON '
+ @table + ' REBUILD;'
PRINT @reindex --prints the reindex command
--EXEC @reindex --uncomment to actually reindex
SELECT @id = MIN(object_id)
FROM sys.tables
WHERE object_id > @id
END
например:
CREATE PROCEDURE dbo.sp_ForEachTable @query varchar(8000) AS
--todo