繁体   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