2017-12-05 20 views
2

아래의 쿼리에서 try catch 블록을 사용하여 오류를 잡으려고합니다. 그러나 쿼리가 오류를 발생시키는 경우에도 쿼리는 catch 블록을 두드리지 않습니다. "SQL Server 2008 R2의 캐치 오류가 없습니다.

메시지 7314, 수준 16, 상태 1, 프로 시저 PROC_NAME, 연결된 서버 라인 97 OLE DB 공급자"SQLNCLI11 "나는 오류가 아래 얻고있다 TRY-CATCH 블록을 사용하지 않고 쿼리를 실행하고 때 LINKEDSERVER "에 테이블" "DB_NAME". "dbo". "VIEW_NAME" "이 (가) 없습니다. 테이블이 존재하지 않거나 현재 사용자에게 해당 테이블에 대한 사용 권한이 없습니다. 메시지 2020, 수준 16, 상태 1, 줄 34 "SP_NAME"엔터티에 대해보고 된 종속성에 모든 열에 대한 참조가 포함되어 있지 않을 수 있습니다. 이는 엔티티가 존재하지 않는 객체를 참조하거나 엔티티의 하나 이상의 명령문에서 오류로 인해 발생합니다. 쿼리를 다시 실행하기 전에 엔티티에 오류가없고 엔티티에서 참조하는 모든 객체가 존재하는지 확인하십시오. 당신은 컴파일 및 런타임 오류를 혼합하는

SELECT DISTINCT NAME INTO #ALL_SPS FROM SYSOBJECTS SO,SYSCOMMENTS SC WHERE SO.ID = SC.ID 
AND TEXT LIKE '%LINKEDSERVER%' 

CREATE TABLE #ERRORS 
(
    ERRORNUMBER VARCHAR(100), 
    ERRORSEVERITY VARCHAR(100), 
    ERRORSTATE VARCHAR(100), 
    ERRORPROCEDURE VARCHAR(100), 
    ERRORLINE VARCHAR(100), 
    ERRORMESSAGE VARCHAR(100) 
) 

CREATE TABLE #TEMP(SP_NAME VARCHAR(500),DB VARCHAR(100), LINKEDSERVER VARCHAR(100)) 

BEGIN  
DECLARE @SP_NAME VARCHAR(MAX) 
DECLARE @STARTTIME DATETIME =GETDATE() 

DECLARE HDR_CURSOR CURSOR FOR 

SELECT NAME FROM #ALL_SPS --IS TEMP TABLE IMPORTED FROM SHARED EXCEL 

OPEN HDR_CURSOR  

FETCH NEXT FROM HDR_CURSOR INTO @SP_NAME 

WHILE (@@FETCH_STATUS = 0)  
    BEGIN  
BEGIN TRY 
BEGIN TRANSACTION; 

    INSERT INTO #TEMP 
    SELECT 
    TBLSQLREFERENCEDENTITY.REFERENCED_ENTITY_NAME AS REFERENCEDENTITY, 
    COALESCE(REFERENCED_DATABASE_NAME,DB_NAME()) AS REFERENCEDDATABASE, 
    COALESCE(TBLSQLREFERENCEDENTITY.REFERENCED_SERVER_NAME,'CURRENT SERVER') AS REFERENCEDSERVER 
    FROM SYS.DM_SQL_REFERENCED_ENTITIES('DBO.'[email protected]_NAME, 'OBJECT') TBLSQLREFERENCEDENTITY 
    WHERE TBLSQLREFERENCEDENTITY.REFERENCED_SERVER_NAME ='LINKEDSERVER' 
    GROUP BY REFERENCED_ENTITY_NAME,REFERENCED_DATABASE_NAME,REFERENCED_SERVER_NAME 
    COMMIT TRANSACTION; 
END TRY 
BEGIN CATCH 

INSERT INTO #ERRORS 
SELECT ERROR_NUMBER() AS ERRORNUMBER 
    ,ERROR_SEVERITY() AS ERRORSEVERITY 
    ,ERROR_STATE() AS ERRORSTATE 
    ,ERROR_PROCEDURE() AS ERRORPROCEDURE 
    ,ERROR_LINE() AS ERRORLINE 
    ,ERROR_MESSAGE() AS ERRORMESSAGE; 

END CATCH 
    FETCH NEXT FROM HDR_CURSOR INTO @SP_NAME 

END  
CLOSE HDR_CURSOR  
DEALLOCATE HDR_CURSOR  
SELECT DATEDIFF(MS,@STARTTIME,GETDATE()) 'TIME TAKEN IN MS' 
SELECT DISTINCT * FROM #TEMP 
SELECT DISTINCT * FROM #ERRORS 

END 
+1

IN "T을 때로 믿을 현재 DB의 개체를 결정 ... 등이 될 뭔가를 할 수 이전 스타일의 쉼표 - 구문 JOIN을 사용하지 마십시오. https://stackoverflow.com/questions/1018822/inner-join-on-vs-where-clause – Shawn

+0

공유 서버에 대한 사용 권한을 두 번 선택하십시오. 적절한 사용자가 공유 테이블에 액세스 할 수 있습니까? – Shawn

+0

@shawn 서버에서 쓰기 및 액세스 권한을 읽었습니다. – Shardul

답변

1

. 해당 테이블에 대한 권한이 가정하면, 더 좋은 방법은

... 
BEGIN TRANSACTION; 

--see if that object exists in your linked server... 
if(select 1 
    from YourLinkedServer.master.sys.objects 
    where [name] = @SP_NAME) is not null 


--if it exists, then insert from it... 
INSERT INTO #TEMP 
SELECT 
TBLSQLREFERENCEDENTITY.REFERENCED_ENTITY_NAME AS REFERENCEDENTITY, 
COALESCE(REFERENCED_DATABASE_NAME,DB_NAME()) AS REFERENCEDDATABASE, 
COALESCE(TBLSQLREFERENCEDENTITY.REFERENCED_SERVER_NAME,'CURRENT SERVER') AS REFERENCEDSERVER 
FROM SYS.DM_SQL_REFERENCED_ENTITIES('DBO.'[email protected]_NAME, 'OBJECT') TBLSQLREFERENCEDENTITY 
WHERE TBLSQLREFERENCEDENTITY.REFERENCED_SERVER_NAME ='LINKEDSERVER' 
GROUP BY REFERENCED_ENTITY_NAME,REFERENCED_DATABASE_NAME,REFERENCED_SERVER_NAME 

COMMIT TRANSACTION; 

... 

연결된 서버

use [theDatabaseYourCareAbout] 

select 
    [name] 
from sys.objects 
where type in ('P','V') --procedures and views 
except 
select 
    [name] 
from YourLinkedServer.master.sys.objects 
where type in ('P','V') --procedures and views 
+0

의견을 공유해 주셔서 감사합니다. 하지만 실제로 실종 된 개체를 추적하여 문서화하고 관련 팀에 알릴 수 있도록 오류를 포착하고 싶습니다. 우리는 시스템 통합 테스팅을하고 있습니다. – Shardul

+0

두 데이터베이스 (예 : 데이터베이스의 모든 개체, 뷰, 저장 프로 시저, 테이블)를 비교할 수있는 방법이 있습니까? 누락 된 개체 또는 스키마가 누락 된 개체와 같은 개체의 차이를 가져옵니다. 테이블 또는 뷰의 열 이름 또는 열 수가 일치하지 않습니다. 참조 용으로 사용할 수 있도록 일부 코드를 공유 할 수 있다면 매우 유용 할 것입니다. – Shardul

+0

잘, 당신은 여전히 ​​런타임 오류를 잡기 위해 그것을 사용할 수 있습니다. 그러나 컴파일 시간 오류를 잡을 수는 없습니다. – scsimon