【问题标题】:Performing query on two databases with stored procedure for returning two sets of data on dropdown使用存储过程对两个数据库执行查询,以在下拉列表中返回两组数据
【发布时间】:2014-09-07 13:34:20
【问题描述】:

我在一个表单上有两个下拉菜单。第二个下拉列表根据在第一个下拉列表中选择的值进行填充。两个存储过程查询中的一个基本上显示了 @LocID 的值不匹配在第一个下拉列表中选择的不存在的数据,并且还执行子查询,其中没有为与声明的 @LocID 匹配的任何内容返回邮政编码。

DECLARE @LocID INT;

SELECT
 DISTINCT l.[ZipCode],
 [Description] = l.ZipCode + ' - ' + l.Description
FROM LocMap l
  WHERE l.ZipCode NOT IN (
  SELECT l2.ZipCode
  FROM LocMap l2
  WHERE l2.LocID = @LocID
);

名为 LocMap 的表。

LocID | ZipCode | Description
----------------------------------
100  | 91012   | Magical Sky
100  | 91013   | Dream Land
101  | 91012   | Blue Ocean
102  | 91012   | Gray Screen
104  | 91014   | Limit Break
108  | 91016   | Magic Hammer

我的问题是我的第二个存储过程,它也将数据返回到标记为“最近添加”的第二个下拉列表。它基本上查询一个表并返回它的所有数据(邮政编码+描述),没有条件或任何东西。我想知道的是是否可以在同一台服务器上查询两个数据库,如果可以,我将如何使用第二个表的存储过程查询对上面的存储过程执行相同的数据过滤.第一个存储过程具有@declare LocID,但第二个存储过程所做的只是返回所有内容而不声明任何内容。

1) 推荐的方法是什么。是否可以从第一个存储过程中获取结果并执行类似于使用最近添加过滤掉我的数据的子查询?就像第一个查询一样,我也不想返回与第二个表结果中传递的 LocID 匹配的任何邮政编码。

名为“RecentAdded”的第二个存储过程表

ZipCode | Description
----------------------------------
91018   | Zelda
91019   | Sephiroth
91012   | Cloud
91012   | Aeris
91011   | Tifa
91010   | Barrett

Dropdown Layout Example

[Select LocID] (First Dropdown)
   100
   104
   108
   120

[Select ZipCode - Description] (Second Dropdown]
  ---Recently Added---
    91010 - Barrett
    91018 - Zelda
    ......................
    ......................
    ......................
  ---All other ZipCodes---
    91016 - Magic Hammer
    91014 - Limit Break
    ......................
    ......................
    ......................

【问题讨论】:

    标签: sql sql-server tsql stored-procedures


    【解决方案1】:

    您可以使用 UNION 运算符一举完成:

    DECLARE @LocID INT;
    
    SELECT DISTINCT
        f.[ZipCode],
        [Description] = f.ZipCode + ' - ' + f.Description,
        f.[RecentlyAdded]
    FROM (
        SELECT
            l.[ZipCode],
            l.[Description],
            RecentlyAdded = CAST(0 AS BIT)
        FROM LocMap l
        UNION
        SELECT
            r.[ZipCode],
            r.[Description],
            RecentlyAdded = CAST(1 AS BIT)
        FROM RecentlyAdded r
    ) f
    WHERE f.ZipCode NOT IN (
        SELECT l2.ZipCode
        FROM LocMap l2
        WHERE l2.LocID = @LocID
    )
    ORDER BY RecentlyAdded DESC;
    

    从两个表中获取输入后,您可以将结果存储为它自己的“表”,并像只查询一个表一样进行过滤/选择。

    确保您在上面适当地更改了最近添加的数据库/架构名称(在帖子中没有看到)。

    SQL Fiddle

    【讨论】:

    • 我正在阅读关于 UNION 的文章,看起来它可以满足我的需要。但是,我认为我只需要使用 UNION 而不是 UNION ALL,因为我不需要在最终结果中包含重复的结果。关于将结果存储在自己的表中,你的意思是它创建一个“虚拟”或某种临时表来进行最终查询,还是我需要实际创建一个新表来存储这些信息?如果我用两个数据库中的两个表组合创建一个视图,然后在我的第一篇文章中使用存储过程来执行查询以查看表而不是数据库,那会更好吗?
    • 这取决于您是否希望最近添加的项目都可能显示在下拉列表的顶部和底部 - 如果不是,UNION 肯定会更合适。至于表,执行引擎会处理所有这些 - 您无需创建临时表/表变量来存储它。如果您打算在其他地方使用它,那么创建一个视图将是一个好主意。
    • 嗯,想看看我做错了什么。你有“final f”的那一行说语法错误。我应该为此添加数据库架构吗?
    • 此外,最近添加的表的列名不同,即使值与邮政编码和描述相关。最初创建这个的人并不是那么聪明。我会仔细检查以确保我的引用正确无误。
    • 从上面的定义中删除了“final”——现在应该可以了。您唯一需要更改的是最近添加的列的名称——只要数据类型兼容就可以了。您必须以其他方式投射它们才能正常工作。让我知道它是否有效。
    【解决方案2】:

    使用临时表来存储中间值,如此处所示。根据具体情况,可能适合使用真正的填表(如图所示)或表值变量。

    create table #t(
        ZipCode  varchar(7)
        ,Description varchar(255)
    );
    -- N.B. Don't insert a **go** here
    
    insert #t (ZipCode,Description)
    exec <second stored procedure name and parameters>;
    
    -- proceed to join to your prior query
    

    【讨论】:

    • 大约 4500 个来自 DB 中表的总结果,所以如果我使用 TEMP 表路由而不是表变量可能会更好,只是为了将来证明,虽然没有复杂的数据类型,也没有使用最大值。我会试试看。
    • 我越来越喜欢这个,但是有点担心这是否会对 SQL Server 性能造成任何问题。 (无论如何都不是高流量服务器)。如果在存储过程会话结束后应该释放 TEMP 表,是否有必要在我的 JOIN 查询之后添加 DROP 临时表?
    • @bman2013:您只需要删除以##(全局临时表)开头的临时表。那些只有一个哈希值的对象在超出范围时会被自动删除。 (当连接被释放时,如果有记忆的话。)然而,作为一个合理的编程实践问题,我总是尝试在不再需要时删除它们。我发现临时表通常可以提高性能,而不是降低性能,但这可能取决于具体情况。但是,在发生特定的性能问题时处理它们,而不是处理您能想到的所有可能的问题。 ...
    • @bman2013: 简单的设计,不会出现性能问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-10
    • 2015-10-06
    • 2018-02-05
    • 1970-01-01
    • 2013-12-01
    • 1970-01-01
    相关资源
    最近更新 更多