2013-06-21 2 views
2

sp_MSforeachtable을 사용하여 모든 테이블에 인덱스를 추가하는 방법은 무엇입니까? 그것은 오류를주고있다.sp_MSforeachtable을 사용하여 여러 줄 쿼리를 실행하는 방법

EXEC sp_MSforeachtable @precommand = 'declare @idx as char;', 
@command1 = ' 
set @idx = ''idx_'' + ? + ''_modified_on''; 
print @idx; 
IF EXISTS (SELECT * FROM sys.indexes WHERE object_id = OBJECT_ID(N''[dbo].[?]'') AND name = N''@idx'') 
    DROP INDEX [@idx] ON [dbo].[?] 

CREATE NONCLUSTERED INDEX [@idx] ON [dbo].[?] 
(
    [modified_on] ASC 
) ON [PRIMARY] 
' 

하나는 이러한 오류 : 나는 명령 내부의 선언을 배치하지만,이 오류 좀하려고

Msg 137, Level 15, State 1, Line 2 
Must declare the scalar variable "@idx". 

: 여기

Msg 4104, Level 16, State 1, Line 3 
The multi-part identifier "dbo.DIAG_contractAuditHistory" could not be bound. 

는에 업데이트 시도 테스트 SQL과 함께 구문 오류를 수정했지만 여전히 이상한 오류가 발생했습니다. 저장 프로 시저로 문제를 해결하고 각 테이블에 대해 저장 프로 시저를 호출했습니다. How do I create an index inside a stored procedure?

:

EXEC sp_MSforeachtable @command1 = ' 
declare @idx as varchar(256); 
set @idx = ''idx_'' + SUBSTRING(''?'', 8, len(''?'')-8) + ''_modified_on''; 
print @idx; 
IF EXISTS (SELECT * FROM sys.indexes WHERE object_id = OBJECT_ID(N''?'') AND name = @idx ) 
    DROP INDEX [@idx] ON ? 

IF EXISTS (select * from sys.columns where object_id = OBJECT_ID(N''?'') and name = ''modified_on'') 
    CREATE NONCLUSTERED INDEX [@idx] ON ? 
    (
     [modified_on] ASC 
    ) ON [PRIMARY] 
' 

declare @cat as char; 
set @cat='dog'; 
print @cat; 

EXEC sp_MSforeachtable 'print ''idx_'' + SUBSTRING(''?'', 8, len(''?'')-8) + ''_modified_on'';' 
EXEC sp_MSforeachtable 'print ''?''' 
print substring('[dbo].[merchantNotes]', 8, (len('[dbo].[merchantNotes]')-9)) 

select * from sys.columns where object_id = OBJECT_ID(N'[dbo].[banks]') and name = 'modified_on' 
SELECT * FROM sys.indexes WHERE object_id = OBJECT_ID(N'contractPaymentHistory') AND name = 'idx_contractPaymentHistory_modified_on' 

이 약 2 다스 테이블을 위해 일 것은, 그것은 그래서 다른 전략을 사용하여 종료 및 인덱스를 만들 수있는 저장 프로 시저를 생성

Msg 1934, Level 16, State 1, Line 9 CREATE 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.

같은 이상한 오류를 준다

+1

@precommand 같은 배치에 있지 않습니다.. 호출 범위/배치에서 실행됩니다. 전역 또는 계층 적 범위 (#temp 테이블과 같은)를 가지는 설정은 DECLARE가 로컬 범위에만 적용됩니다. – RBarryYoung

답변

2

이전에 @precommand을 사용해 본 적이 없지만,이 부분을 @command1에 추가하면 제대로 작동합니다.

두 번째 문제는 ?을 사용하는 방법과 관련이 있습니다. 실제로는 이미 dbo 스키마가 포함되어 있습니다. 부품 번호 OBJECT_ID(N''[dbo].[?]'')OBJECT_ID("?")으로 교체하고 CREATEDROP INDEX 문에도 동일하게 적용하십시오.

편집 :이 코드는 작동합니다

.

EXEC sp_MSforeachtable 
    ' 
     declare @idx as char; 
     set @idx = ''idx_'' + "?" + ''_modified_on''; 
     IF EXISTS (SELECT * FROM sys.indexes WHERE object_id = OBJECT_ID("?") AND name = N''@idx'') 
      DROP INDEX [@idx] ON ? 

     CREATE NONCLUSTERED INDEX [@idx] ON ? 
     (
      [modified_on] ASC 
     ) ON [PRIMARY] 
    ' 
+0

그것은 질문의 일부입니다. '나는 선언문을 명령 안에 넣으려고합니다.'다른 전략을 시도 할 때 구문 오류를 찾고 있지만 그들을 지적 해 주셔서 감사합니다. – Chloe

+1

원본 답변에서 구문 오류를 이미 설명했습니다. 코드에서 '?'를 사용하는 방식을 살펴보십시오. 나는'set @ idx'에서 사용한'?'을 놓쳤지 만, 내가 제공 한 정보로 자신을 알아 냈어야합니다.답변이 정확하지 않은 경우에도 도움을 주려는 사람들을 혼란스럽게하는 것은 좋지 않습니다. – JodyT

1

명령에 idx를 선언 할 수 있습니다. 다른 구문 오류가 있습니다. 투표. 당신의 오류는 declare 문과 아무 관련이 없습니다. ?을 잘못 사용했기 때문입니다. sp_msforeachtable은 간단한 교체 작업을 수행합니다. 귀하의 사용에 대한 그래서, 당신은 외부 문자열을 인용을 끝내하지 않는, 오히려 그것을 (인용하거나 할 필요가있다.

를이 여전히 작동하지 않습니다 이유에 your other question에 대한 내 대답을 참조하십시오. 여기

는 프리 핸드 corrected-입니다 틱 버전 :.

EXEC sp_MSforeachtable 
@command1 = ' 
declare @idx nvarchar(1000); 
declare @tbl nvarchar(1000); 
set @tbl = replace(''?'', ''[dbo].'', ''''); 
set @tbl = left(@tbl, len(@tbl) - 1); 
set @idx = ''idx_'' + @tbl + ''_modified_on''; 
print @idx; 
IF EXISTS (SELECT * FROM sys.indexes WHERE object_id = OBJECT_ID(N''?'') AND name = N''@idx'') 
    DROP INDEX [@idx] ON ?; 
declare @sql nvarchar(1000); 
set @sql = '' 
CREATE NONCLUSTERED INDEX ['' + @idx + ''] ON ? 
(
    [modified_on] ASC 
) ON [PRIMARY]''; 
exec sp_executesql @sql; 
'; 

나는 당신이이 일을하는 이유를 질문한다 혼자 해당 필드를 인덱싱하면 일을 할 수있다만큼 좋지 않다 covering indexes 읽기 최대

+1

@ Chloe 투표를하기 전에 두 번 생각해야합니다. 당신의 오류는 declare 문과 아무 관련이 없습니다. '? '를 잘못 사용했기 때문입니다. sp_msforeachtable은 간단한 대체 작업을 수행합니다. 그래서 당신의 사용을 위해, 당신은 그것을 인용 할 필요가있다. (아니면 오히려 바깥 쪽 문자열을 인용 부호로 묶지 말아야한다.) –

+1

@Chloe 또한 다른 질문과 마찬가지로 CREATE INDEX 문에서 변수를 사용하려고 시도하고있다. –

+0

그것은 '명령 안에 선언을 넣으려고합니다.'라는 질문의 일부였습니다.이 인덱스는 ETL 도구가 여러 공급 업체 간의 데이터베이스를 동기화하는 데 사용됩니다. 링크는 클러스터 된 인덱스를 참조했습니다. 관련성이 높을수록 더 깊이 읽는 것이 좋겠지 만 제한된 예산으로 인해 나중에 연기해야합니다.이 방법을 다시 시도해 보겠습니다. – Chloe

관련 문제