如果结果存在,则显示查询结果,而无需再次运行同一查询

时间:2018-11-28 19:38:26

标签: sql sql-server ssms sql-server-2014

我想要一个存储过程,该过程将输入一个SerialNumber nvarchar作为输入,并检查几个数据库以查看该序列号是否存在以及是否存在,然后返回查询结果,否则移至下一个数据库并做同样的事情,直到检查完所有数据库为止。

当前伪代码:

IF(exists(select top 1 * from Server1.Database1.Table where num = @SerialNumberInput))
BEGIN
    select top 1 * from Server1.Database1.Table where num = @SerialNumberInput
END ELSE
    IF(exists(select top 1 * from Server2.Database2.Table where num = @SerialNumberInput))
BEGIN
    select top 1 * from Server2.Database2.Table where num = @SerialNumberInput
END ELSE
--Server3.Database3
--Server4.Database4
--etc...

但是我不喜欢所有这样的查询重复,而且我不喜欢如何通过两次调用相同的查询来两次调用服务器。我可以将结果保存到一个表变量中,然后检查一下,但是感觉很黑。

1 个答案:

答案 0 :(得分:1)

评论太久了。

  

但是我不喜欢所有这样的查询重复

我也不是,但是在这种情况下,这是最干净的方法或最易读懂的恕我直言。

  

我不喜欢这样两次必须打一次服务器电话   两次调用相同的查询。

您不是,至少不是完全一样。 EXISTS返回一个BOOLEAN值,只要您的谓词上有一个INDEX,它就应该很快。第二个查询(您将返回包含所有列的第一行)会稍微慢一些。另外,除非您愿意,否则top 1 *中不需要EXISTS。您可以使用SELECT 1任何,因为结果是BOOLEAN

另一件事是您正在使用不带TOPORDER BY的{​​{1}},这意味着您不必关心返回的行,并且每次执行此行时(可能)该行都不同(可以)就可以了。 More on that in this blog.

如果您真的不想使用EXISTS,则可以使用@@ROWCOUNT进行分解。

select top 1 * from Server1.Database1.Table where num = @SerialNumberInput
if @@ROWCOUNT = 1
   return
else
select top 1 * from Server2.Database2.Table where num = @SerialNumberInput
if @@ROWCOUNT = 1
   return
else
...

或者,如果架构相同,并且您不想要NULL数据集……就像您对表变量所说的那样。

create table #Temp(...)

insert into #Temp
select top 1 * from Server1.Database1.Table where num = @SerialNumberInput
if @@ROWCOUNT = 1
    select * from #Temp
    return
else
insert into #Temp
select top 1 * from Server2.Database2.Table where num = @SerialNumberInput
if @@ROWCOUNT = 1
    select * from #Temp
    return
else
...

由于您仅插入一行,因此很快。自然,较大的数据集将花费更长的时间。