代码之家  ›  专栏  ›  技术社区  ›  Jimmy Chandra

当您多次运行SELECT*FROM multiple table JOIN时,在两次执行之间是否可能以不同的列顺序返回数据?

  •  0
  • Jimmy Chandra  · 技术社区  · 15 年前

    例如,我有以下表格,这些表格是由:

    CREATE TABLE A (Id int, BId int, Number int)
    CREATE TABLE B (Id int, Number decimal(10,2))
    GO
    INSERT INTO A VALUES(1, 3, 10)
    INSERT INTO B VALUES(3, 50)
    INSERT INTO A VALUES(2, 5, 20)
    INSERT INTO B VALUES(5, 671.35)
    GO
    

    我多次运行以下查询:

    SELECT * FROM A INNER JOIN B ON A.BId = B.Id
    

    我应该得到类似于:

    ID  BId  Number  ID  Number
     1    3      10   3   50.00
     2    5      20   5  671.35
    

    但A.Number和B.Number列是否可能处于不同的位置(在这方面也是ID),因此我将得到如下结果:

    ID  Number  ID  BId  Number
     3   50.00   1    3      10
     5  671.35   2    5      20
    

    我们发现有时会出现如下错误:

    无法将“System.Decimal”类型的对象转换为“System.Int32”类型

    试图找出这是SQL Server中的行为还是基于反射的数据映射器引擎中的行为。

    正如您所看到的,这两个表中的字段名是相同的。也许当我们尝试执行DataReader.GetValue(DataReader.GetOrdinal(“Number”))时,它会返回B.Number(十进制),而不是a.Number(整数)。

    使问题进一步复杂化的是,这种情况只会间歇性地发生(但仅在web场中的特定IIS web服务器上发生一次之后才持续发生)。

    假设Web服务器A在下午2:00之前运行正常,突然,我们出现了此错误,我们将继续在Web服务器A上出现此错误,直到我们在该服务器上重置IIS,然后它将再次正常运行。

    连接池和SQL查询计划如何缓存?

    4 回复  |  直到 15 年前
        1
  •  1
  •   Prashanth    15 年前

    第二种情况只有在交换表顺序时才可能出现。

    类似于SELECT*FROM B内部连接A上的A.BId=B.Id。

    否则就不可能了。

        2
  •  1
  •   paxdiablo    15 年前

    SQL是一个关系代数-如果您自己没有明确说明顺序,标准不会指定返回的顺序列。

    我倾向于回避 "select *"

    只需选择实际需要的列。

    对于您的特定情况,我还将只返回共享ID一次,因为由于您的连接,共享ID必须相等(我倾向于使用“旧”样式,因为DBMS应该足够聪明,可以将其优化为内部连接):

    select
        a.Id as Id,
        a.BId as BId,
        a.Number as Number,
        b.Number as BNumber
    from
        a, b
    where
        a.BId = b.Id
    
        3
  •  1
  •   Niikola    15 年前

    第二种情况只有在交换表顺序时才可能出现。

    联接顺序与列的位置无关,除非使用不推荐的简单选择*。

    即使在这种情况下,您也可以使用

    选择B。 A. 不改变连接顺序

    --后来添加

    我忘了我想指出的另一件事:对具有相同名称的列使用列别名。

    选择A.编号作为编号A,B.编号作为编号B

        4
  •  0
  •   Marc Gravell    15 年前

    我不认为我见过它交换订单,但我个人不使用“ SELECT * “在生产代码中,可以:

    SELECT A.[Id], A.[Bid], A.[Number], B.[Id], b.[Number]
    FROM A INNER JOIN B ON A.[BId] = B.[Id]
    

    或者最坏的情况是:

    SELECT A.*, B.* FROM A INNER JOIN B ON A.[BId] = B.[Id]