在SQL查询中尝试/捕获多个联合

时间:2018-09-27 15:06:50

标签: sql sql-server

我有一个相当大的SQL查询,该查询在多个表之间执行联合。这用于每小时运行一次的自动化运行。有时,这些表将被重建,当查询运行时,我最终会收到一个无效的对象名SQL异常,因为在重建表时该表丢失了。

作为一个完全掌握SQL的新手,我的问题是这个

  1. 我可以在一个查询中包含多个Try / Catchs
  2. 如果是的话,我怎么能不理会抛出错误的那个联合并继续前进呢?

这是查询的示例,包括我想用try catch包围的并集。我的目标是简单地检查该联合是否有效,如果没有发现错误,然后继续下一个联合

...

union
SELECT [projectID] as ProjectID
FROM [Store].[dbo].[lemon_table]
WHERE modifiedDateTime >= @StartTime

union
SELECT [projectID] as ProjectID
FROM [Store].[dbo].[apple_table]
WHERE modifiedDateTime >= @StartTime

union
SELECT [projectID] as ProjectID
FROM [Store].[dbo].[orange_table]
WHERE modifiedDateTime >= @StartTime

....

真的会这么简单吗?

...

BEGIN TRY
union
SELECT [projectID] as ProjectID
FROM [Store].[dbo].[lemon_table]
WHERE modifiedDateTime >= @StartTime
END TRY
BEGIN CATCH
END CATCH

BEGIN TRY
union
SELECT [projectID] as ProjectID
FROM [Store].[dbo].[apple_table]
WHERE modifiedDateTime >= @StartTime
END TRY
BEGIN CATCH
END CATCH

BEGIN TRY
union
SELECT [projectID] as ProjectID
FROM [Store].[dbo].[orange_table]
WHERE modifiedDateTime >= @StartTime
END TRY
BEGIN CATCH
END CATCH

....

此外,由于这个原因而导致的SQL异常是否会被捕获,或者是“高”错误? “ System.Data.SqlClient.SqlException:无效的对象名称”

2 个答案:

答案 0 :(得分:1)

您可以使用临时表或表变量,并使用单独的try catch或如果存在的块将数据收集到其中 然后您可以选择如下所示的所有值

DECLARE @result TABLE 
       ( 
       project_id int NOT NULL, 

       ) 


    BEGIN TRY
      Insert into @Result (project_Id)
      SELECT [projectID] as ProjectID
      FROM [Store].[dbo].[lemon_table]
      WHERE modifiedDateTime >= @StartTime
    END TRY
    BEGIN CATCH
    END CATCH

    BEGIN TRY
      Insert into @Result (project_Id)
      SELECT [projectID] as ProjectID
      FROM [Store].[dbo].[apple_table]
      WHERE modifiedDateTime >= @StartTime
    END TRY
    BEGIN CATCH
    END CATCH

    BEGIN TRY
      Insert into @Result (project_Id)
      SELECT [projectID] as ProjectID
      FROM [Store].[dbo].[orange_table]
      WHERE modifiedDateTime >= @StartTime
    END TRY
    BEGIN CATCH
    END CATCH

    select * from @result

答案 1 :(得分:1)

使用Dynamic SQL可能不是最好的方法,但可能是其中一种方法:

在进入以下查询之前,假设您已经有一个查询以返回所有现有的Fruits表,并具有一个临时表或永久表来存储结果。假设我们在示例中输入了3个,则:

/* this only simulates above assumption
CREATE TABLE #AllExistingTables 
(
TableName VARCHAR(50),
[Id] INT IDENTITY(1,1)
)
INSERT INTO #AllExistingTables
VALUES('Lemon'),('Apple'),('Orange')
*/

--Actual query:
DECLARE @Value_StartTime DATETIME = GETDATE()  --SET IT TO YOUR LOCAL VALUE
DECLARE @SQL VARCHAR(MAX) = ''
DECLARE @Control INT 
DECLARE @Loop INT = 1

SELECT @Control = MAX(Id) FROM #AllExistingTables PRINT @Control

WHILE (@Loop <= @Control)
BEGIN
      SELECT @SQL = @SQL + ' UNION SELECT [projectID] as ProjectID FROM ' + TableName + ' WHERE modifiedDateTime >= @StartTime'
      FROM #AllExistingTables
      WHERE Id = @Loop

      SET @Loop = @Loop + 1
END

SET @SQL = STUFF(@SQL,1,7,'')  --remove the 1st 'union' word

EXECUTE sp_executesql @SQL, '@StartTime DateTime', @StartTime = @Value_StartTime

上面的查询有一个潜在的问题,如果您有很多种类的水果,@SQL将被截断为8000个字符,这将使您的动态查询不完整。