[英]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
您可以尝试使用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.