2017-07-18 43 views
0

在我的查詢我必須從分貝,是不是我的控制之下連接表。這有時會讓我瘋狂,因爲有時候這個數據庫無法訪問(請不要問我爲什麼),這打破了我的查詢。我加入的字段是根本對我的業務,​​我想我的應用程序正常工作,即使這些字段是不是在同一時間訪問。SQL服務器:在查詢錯誤捕獲

這裏的數據結構,我沒有自己:

[DBOutOfControl].[dbo].[Table1]: 
[Field1] 
[Field2] 

[DBOutOfControl].[dbo].[Table2]: 
[Field1] 
[Field2] 
[Field3] 

這裏是我的表:

[DBInMyControl].[dbo].[Table3]: 
[Field1] 

我原來的查詢看起來就像這樣:

SELECT [Table3].[MyID], 
     [ForeignDataQry].[A], 
     [ForeignDataQry].[B] 
FROM [DBInMyControl].[dbo].[Table3] 
LEFT JOIN 
    (SELECT [Table1].[Field1] AS [MyID], 
      [Table1].[Field2] AS [A], 
      [SubQry].[Field2] AS [B] 
    FROM [DBOutOfControl].[dbo].[Table1] 
    LEFT JOIN 
    (SELECT [Table2].[Field1], 
      [Table2].[Field2] 
     FROM [DBOutOfControl].[dbo].[Table2] 
     WHERE [Table2].[Field3] = 'Where') AS [SubQry] ON [Table1].[Field1] = [SubQry].[Field1]) AS [ForeignDataQry] ON [Table3].[MyID]=[ForeignDataQry].[MyID] 

如何如果[ForeignDataQry]產生錯誤,結果可能是:

[MyID] [A] [B] 
1  NULL NULL 

否則

[MyID] [A] [B] 
1  Va1 Val2 

有什麼可以做,服務器端?

+0

的[防止錯誤可能的複製時,目標數據庫中恢復模式(SQL編制)(https://stackoverflow.com/questions/18630367/prevent-error-when-target-database-in-restore-mode-sql-preparation) – Tanner

+0

當另一個數據庫不能訪問你的代碼不能被編譯,所以你唯一能做的就是嘗試在另一個(內部)上下文中執行它,用動態sql包裝它,如果它成功則什麼也不做,如果沒有,外層try..catch會捕獲它,然後你執行另一個代碼而不引用不可訪問的對象 – sepupic

回答

0

只要指定的預期結果COUNT,三個名字,你可以事先檢查表。 A小調重寫可以允​​許這種檢查比表等物,如果需要利用EXISTS,跳過或添加更多的檢查,等:

IF 0 = (-- Specify how many records you expect to come. 
    SELECT COUNT(C.[name]) AS [COUNT] 
    FROM sys.objects AS O 
    LEFT JOIN sys.schemas AS S ON S.schema_id = O.schema_id 
    LEFT JOIN sys.columns AS C ON C.object_id = O.object_id 
    WHERE O.[name] = 'tablename' 
     AND S.[name] = 'schemaname' 
     AND C.[name] = 'columnname' 
) 
    SELECT 1 AS A -- Do some code. 
ELSE 
    SELECT 2 AS B -- Do some other code. 
+0

爲什麼sys.databases中不會有這個數據庫? – sepupic

+0

它可以只是不在線,或對應於應用程序的用戶可能會缺失:在OP不中不準確什麼意義的數據庫不能訪問 – sepupic

+0

@sepupic,是我使用的是過時呢?我只是把它作爲參考,我對這些東西沒有太多參與,這也讓我不知道各種不可訪問性。 – KtX2SkD

0

我包裹在動態代碼有問題的查詢,以便能夠趕上編譯錯誤(我們不能在同一個範圍內趕上)是這樣的:

begin try 
    declare @sql varchar(4000) = 

     'SELECT [Table3].[MyID], 
       [ForeignDataQry].[A], 
       [ForeignDataQry].[B] 
     FROM [DBInMyControl].[dbo].[Table3] 
     LEFT JOIN 
      (SELECT [Table1].[Field1] AS [MyID], 
        [Table1].[Field2] AS [A], 
        [SubQry].[Field2] AS [B] 
      FROM [DBOutOfControl].[dbo].[Table1] 
      LEFT JOIN 
      (SELECT [Table2].[Field1], 
        [Table2].[Field2] 
       FROM [DBOutOfControl].[dbo].[Table2] 
       WHERE [Table2].[Field3] = ''Where'') AS [SubQry] ON [Table1].[Field1] = [SubQry].[Field1]) AS [ForeignDataQry] ON [Table3].[MyID]=[ForeignDataQry].[MyID]' 
     exec(@sql) 
    end try 
    begin catch 
     SELECT [Table3].[MyID], 
       cast(null as ...)as [A], 
       cast(null as ...) as [B] 
     FROM [DBInMyControl].[dbo].[Table3] 
    end catch 

這裏我用cast(null as ...)as [A]得到同樣的類型[ForeignDataQry].[A]有,例如,如果[ForeignDataQry].[A]爲int應該是int:cast(null as int)as [A]

0

我以不同的方式處理了這個問題,但我仍然想要,但無論如何:

我創建了一個[表4],用於保存外部表中記錄的副本 - 字段匹配[ForeignDataQry] +時間戳。我創建過程:

CREATE PROCEDURE [dbo].[CopyForeignData] 
AS 

DECLARE @Timestamp datetime 
SET @Timestamp = getdate() 

BEGIN 
    INSERT INTO [DBInMyControl].[dbo].[Table4] ([MyID], [A], [B], [Timestamp]) 
    SELECT [Table1].[Field1] AS [MyID], 
      [Table1].[Field2] AS [A], 
      [SubQry].[Field2] AS [B], 
      @Timestamp 
    FROM [DBOutOfControl].[dbo].[Table1] 
    LEFT JOIN 
    (SELECT [Table2].[Field1], 
      [Table2].[Field2] 
     FROM [DBOutOfControl].[dbo].[Table2] 
     WHERE [Table2].[Field3] = 'Where') AS [SubQry] ON [Table1].[Field1] = [SubQry].[Field1] 

    DELETE FROM [DBInMyControl].[dbo].[Table4] WHERE [Timestamp] <> @Timestamp 
END 

我會打電話每次都是這樣,當我開始我的應用程序和處理的錯誤和修改我的主要LEFT JOIN指[表4]