1

인용 부호가있는 식별자를 off로 설정하여 생성 된 많은 객체를 사용하는 2008-R2 서버의 old-ish 데이터베이스로 현재 작업하고 있습니다.기존 제한/규칙/절차에서 Quoted_Identifier 변경하기

것은 나는 주로이 유형에서 찾고 : 지금 내가 심지어 제약 조건을 변경할 수 없습니다 것을 발견 나를 바로 난처한 상황에 빠진 한 따옴표 붙은 식별자 설정을 변경하려고

CHECK_CONSTRAINT 
DEFAULT_CONSTRAINT 
RULE 
SQL_SCALAR_FUNCTION 
SQL_STORED_PROCEDURE 
SQL_TRIGGER 
VIEW 

.

제약 조건 : 어떻게 든 임시 복제본/복사를 만들고 원래 복사본을 삭제 한 다음 사본과 Quoted_Identifier를 ON으로 설정하여 다시 만들어야한다고 생각하지만 실제로 어떻게해야하는지 모릅니다. 내 SQL 기술이 제한되어 있기 때문에이를 자동화하는 방법이 있습니다. 누군가 나를 도울 수 있습니까? 아니면 누군가가 더 쉬운 대안 방법을 알고 있습니까?

답변

0

이 데이터베이스를 스크립팅하고 모든 Quoted_Identifier OFF를 제거한 다음 스크립트에서 데이터베이스를 다시 만들고 데이터를 다시 가져옵니다 (마법사는 MS SS에 포함됨).

이 솔루션의 다양한 맛이있을 수 있습니다. 동적 SQL/SMO 기술로 해결 유사 질문 : Change the ANSI_NULLS setting for all Stored Procedures in the Database

4

나는, (문제가 발동, 함수, 트리거를 스팬 QUOTED_IDENTIFIER가 OFF 객체의 매우 많은 수에 걸쳐 무작위로 ON /로 인한 설치 과정에서 버그가 있었다 및 전망 ...).

필터링 된 색인 및 검색어 알림을 사용하려면 QUOTED_IDENTIFIER이 (가) 필요하므로 모든 항목을 찾은 다음 사용을 설정하는 방법을 원했습니다.

이 사이트에서이 문제를 조사한 결과이 게시물 (및 기타 여러 게시물)이 발견되었지만 모든 SQL 스크립트를 다시 생성하지 않고도이를 수행 할 수있는 좋은 방법은 없었습니다. 고정) 또는 C# 코드 작성.

그래서 SQL 처리 방식을 개발했습니다. 이렇게하면 모든 procs를 다시 컴파일하고 어떤 이유로 든 컴파일 할 수없는 목록을 생성합니다. 나는 이것이 다양한 스키마 (dbo 대 sales 대 무엇이든지)를 다루지 않는다는 것을 알고 있지만, 필요에 따라 그것을 적용 할 수 있습니다. 내 경우에는 그것에 대해 걱정할 필요가 없었습니다.

SET NOCOUNT ON 

    -- MAKE SURE THIS IS ON!! 
    SET QUOTED_IDENTIFIER ON 

    --- Used in try/catch below 
    DECLARE @ErrorMessage nvarchar(4000); 
    DECLARE @ErrorSeverity int; 
    DECLARE @ErrorState int; 

    DECLARE @name sysname 
    DECLARE @type char(2) 
    DECLARE @objType nvarchar(50) 
    DECLARE @createCommand nvarchar(max) 
    DECLARE @dropCommand nvarchar(max) 
    DECLARE @success bit 

    IF OBJECT_ID(N'tempdb..#ProcList', N'U') IS NOT NULL DROP TABLE #ProcList 

    CREATE TABLE #ProcList 
    (
     name   sysname   NOT NULL PRIMARY KEY, 
     id    int    NOT NULL, 
     type   char(2)   NOT NULL, 
     definition  nvarchar(max) NULL, 
     alterstmt  nvarchar(max) NULL, 
     processed  bit    NOT NULL, 
     successful  bit    NOT NULL 
    ) 

    --- Build the list of objects that have quoted_identifier off 
    INSERT INTO #ProcList 
    SELECT 
     so.name, 
     so.object_id, 
     so.type, 
     sm.definition, 
     NULL, 
     0, 
     0 
    FROM sys.objects so 
     INNER JOIN sys.sql_modules sm 
      ON so.object_id = sm.object_id 
    WHERE 
     LEFT(so.name, 3) NOT IN ('sp_', 'xp_', 'ms_') 
     AND sm.uses_quoted_identifier = 0 
    ORDER BY 
     name 

    -- Get the first object 
    SELECT @name = MIN(name) FROM #ProcList WHERE processed = 0 

    --- As long as we have one, keep going 
    WHILE (@name IS NOT NULL) 
    BEGIN 

     SELECT 
      @createCommand = definition, 
      @type = type 
     FROM #ProcList 
     WHERE name = @name 

     --- Determine what type of object it is 
     SET @objType = CASE @type 
       WHEN 'P' THEN 'PROCEDURE' 
       WHEN 'TF' THEN 'FUNCTION' 
       WHEN 'IF' THEN 'FUNCTION' 
       WHEN 'FN' THEN 'FUNCTION' 
       WHEN 'V' THEN 'VIEW' 
       WHEN 'TR' THEN 'TRIGGER' 
      END 

     --- Create the drop command 
     SET @dropCommand = 'DROP ' + @objType + ' ' + @name 

     --- record the drop statement that we are going to execute 
     UPDATE #ProcList 
     SET 
      processed = 1, 
      alterstmt = @dropCommand 
     WHERE name = @name 

     --- Assume we will not succeed 
     SET @success = 0 

     BEGIN TRANSACTION 

     --- Drop the current proc 
     EXEC sp_executesql @dropCommand 

     BEGIN TRY 

      --- Execute the create statement from the definition 
      EXEC sp_executesql @createCommand 

      --- If we reached this point, it all worked 
      SET @success = 1 

      COMMIT 

     END TRY 
     BEGIN CATCH 

      --- oops something went wrong 
      SELECT 
       @ErrorMessage = ERROR_MESSAGE(), 
       @ErrorSeverity = ERROR_SEVERITY(), 
       @ErrorState = ERROR_STATE(); 

      PRINT 'Error processing ' + @name 
      RAISERROR (@ErrorMessage, @ErrorSeverity, @ErrorState, @name) 

      --- Undo the transaction, which undoes the drop above 
      ROLLBACK 

     END CATCH 

     --- At this point, there should be no open transactions 
     IF @@TRANCOUNT > 0 
     BEGIN 
      PRINT 'ERROR... transaction count not right!!' 
      ROLLBACK 
      RETURN 
     END 

     --- check to make sure the object still exists after executing the alter statement, and that we didn't detect an earlier error 
     --- If it's all good, then mark the proc as having been successful 
     IF (
      @success = 1 
      AND EXISTS (
       SELECT name 
       FROM sys.objects so 
        INNER JOIN sys.sql_modules sm 
         ON so.object_id = sm.object_id 
       WHERE name = @name 
      ) 
     ) 
     BEGIN 
      UPDATE #ProcList SET successful = 1 WHERE name = @name 
     END  

     -- Get the next one... if none are left the result will be NULL 
     SELECT @name = MIN(name) FROM #ProcList where processed = 0 

    END 

    -- What wasn't successful?? 
    SELECT * 
    FROM #ProcList 
    WHERE successful = 0 
    ORDER BY name 
+0

스크립트가 도움이되었습니다. 감사합니다. – knkarthick24