2009-07-01 43 views
0

例如我有以下表从产生:当您多次运行SELECT * FROM多个表连接时,在执行之间以不同列顺序返回数据是否可能?

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和Column B.Number可能位于不同的位置(在这方面也是ID),所以我会得到类似于:

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

我们目前正在经历一些奇怪的问题,可能是由于这样的事情造成的。我们有一个ASP.NET应用程序,执行连接到SQL Server 2008群集的基于自定义反射的代码生成数据映射器。

我们有时会发现,我们得到一个错误,像这样:

型“System.Decimal”的对象不能转换为类型“System.Int32”

试图找出如果这是SQL Server中的行为或它在基于反射的数据映射器引擎中的行为。

正如您所见,两个表中的字段名称相同。或许当我们试图做DataReader.GetValue(DataReader.GetOrdinal(“Number”))时,它会返回B.Number,它是一个十进制数,而不是A.Number,它是一个int。

使事情进一步复杂化,这只会间歇性地发生(但始终在Web场中的特定IIS Web服务器上发生一次后)。

说Web服务器A正在正常工作,直到下午2点,突然,我们得到了这个错误,我们将继续在Web服务器A上得到这个错误,直到我们重置该服务器上的IIS,然后它会再次好起来。

w /连接池和SQL查询计划如何缓存可能吗?

+0

一些更多的信息: 由OR映射器生成的SELECT *语句。 我想我们都一致认为: 1. SELECT *永远不会被使用 2.返回的列的顺序在查询执行之间不会改变(我也测试过这个,在1百万次运行中,它停留在相同)。 看起来像罪魁祸首可能在自定义的.NET或Mapper方面。将不得不在那里追逐它。 – 2009-07-01 10:32:50

+0

请记住,如果您使用的是ORM,则应该知道正在生成SQl。从您的描述中可以看出,它不会生成相同的SQL。您可以使用Profiler来检查发送的内容。或者当然,你可以简单地停止使用那些会产生很差的代码的东西(SELECT *实际上总是不是生产中的好主意)。如果不知道如何使用select *(哪一天是数据库新手错误),那么编写ORM的人真正理解如何编写表现良好并且正确的SQL的可能性实际上是渺茫的。 – HLGEM 2013-05-14 21:38:52

回答

1

第二种情况只有在您交换表格订单时才有可能。

喜欢的东西SELECT * FROM乙INNER JOIN A ON A.BId = B.Id.

否则其不可能的。

0

我不认为我见过它交换顺序,但我个人不生产代码中使用“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] 
1

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

我倾向于尽可能避免使用"select *",因为它可能会堵塞网络,造成不必要的流量,并且使得更难以理解列重命名和排序等事情,直到为时已晚。

只需选择您实际需要的列。

对于你的具体情况,我也只是返回共享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 
1

只有在您互换表格订单时,第二种情况才有可能。

连接的顺序与列的位置无关,除非您使用简单的SELECT *,这是不推荐的。

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

SELECT B. ,A不改变顺序加入

最好的和推荐的解决方案是将列名改为*(截至张贴在1号两个答案)

- 后来添加

我忘了一两件事,我想指出的:使用列别名具有相同名称如列

选择A.Number为NumberA,B.Number作为NumberB

相关问题