簡體   English   中英

如果缺少表而不是拋出“無效的 object 名稱”錯誤,如何強制 SQL 語句執行不同的 select?

[英]How to force a SQL statement to do a different select if a table is missing instead of throwing the 'invalid object name' error?

我有一個 SQL 語句,我針對大量 SQL 服務器實例運行,以收集有關服務帳戶的數據。 SQL 語句包含一個管理視圖,該視圖在 SQL 服務器的所有版本中均不可用,當它不可用時,我希望它返回“數據不可用”而不是錯誤輸出。 這似乎是 try/catch 或 if/else 的一個簡單案例,但事實並非如此。 相反,SQL 服務器引擎對其進行評估並在進入 try/catch 或 if/else 邏輯之前拋出“無效的 object 名稱”錯誤。

例子:

-- Example 1
IF EXISTS (SELECT * FROM sys.dm_server_services) 
BEGIN
   SELECT * FROM sys.dm_server_services 
END
ELSE
BEGIN
    SELECT 'No Data'
END

-- Example 2

BEGIN
    BEGIN TRY
        SELECT * FROM sys.dm_server_services
    END TRY
    BEGIN CATCH
        SELECT  
            'No data available' as Service_Account
            ,ERROR_NUMBER() AS ErrorNumber  
             ,ERROR_MESSAGE() AS ErrorMessage;  
    END CATCH
END;
GO

在這兩種情況下, sys.dm_server_services在運行時都會得到一條紅色波浪線和一個無效的 object 錯誤,而不是評估為假,然后執行邏輯的第二部分。

有小費嗎?

一種可能的方法是使用OBJECT_ID()和動態語句。

IF OBJECT_ID ('sys.dm_server_services') IS NULL
BEGIN
   --SELECT 1
   EXEC sp_executesql N'SELECT ''No data'' '
END
ELSE
BEGIN
    --SELECT 2
    EXEC sp_executesql N'SELECT * FROM sys.dm_server_services'
END
-- find if the object exists
IF EXISTS (
    SELECT 1
    FROM sys.all_objects o WITH (NOLOCK)
        JOIN sys.schemas s WITH (NOLOCK)
            ON s.schema_id = o.schema_id
    WHERE o.name = 'dm_server_services'
        AND s.name = 'sys'

) BEGIN
    --execute the query using dynamic SQL
    EXEC sp_executesql N'SELECT * FROM sys.dm_server_services';

END ELSE BEGIN
    SELECT 'No Data'
END

批准的解決方案,請試試這個

IF NOT EXISTS (SELECT * 
               FROM   sys.objects 
               WHERE  object_id = Object_id(N'[dbo].[YourTableName]') 
                      AND type IN ( N'U' )) 
  BEGIN 
  --Your SQL statement 
  END 

參考鏈接https://stackoverflow.com/a/5952051/6923146

您可以嘗試使用INFORMATION_SCHEMA 那里有關於服務器中包含的表和視圖的所有信息。

例子:

SELECT *
FROM sys.INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME= "dm_server_services"

會返回類似的東西

TABLE_CATALOG   TABLE_SCHEMA   TABLE_NAME               TABLE_TYPE
sys             dbo            dm_server_services       BASE TABLE

然后您可以使用EXISTS() function 檢查此查詢是否返回結果並相應地修改您的查詢。

所以你的例子可能變成:

IF EXISTS (SELECT * 
           FROM sys.INFORMATION_SCHEMA.TABLES
           WHERE TABLE_NAME= "dm_server_services") 
BEGIN
   SELECT 1 
END
ELSE
BEGIN
    SELECT 2
END

使用的來源: https://chartio.com/resources/tutorials/sql-server-list-tables-how-to-show-all-tables/

> BEGIN
>     BEGIN TRY
>         SELECT (1/0) counts,* FROM sys.dm_server_services
>     END TRY
>     BEGIN CATCH
>         SELECT  
>             'No data available' as Service_Account
>             ,ERROR_NUMBER() AS ErrorNumber  
>              ,ERROR_MESSAGE() AS ErrorMessage;  
>     END CATCH END; 
GO

如果捕獲到異常,此查詢將按您的預期工作

還給出 output 為:

|Service_Account   | ErrorNumber    |ErrorMessage                     |   
|------------------|----------------|---------------------------------|  
|No data available |8134            |Divide by zero error encountered.|

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM