我有一个查询,该查询使用临时表插入一些数据,然后从中进行另一个选择以提取不同的结果。这个查询本身很好,但是现在有了实体框架,它会在错误的时间导致各种意外错误。
有什么办法可以重写查询而不使用临时表?将其转换为存储过程后,在实体框架中,结果集的类型为int
,将引发错误:
找不到查询模式的实现选择未找到。
这是查询
Drop Table IF EXISTS #Temp
SELECT
a.ReceiverID,
a.AntennaID,
a.AntennaName into #Temp
FROM RFIDReceiverAntenna a
full join Station b ON (a.ReceiverID = b.ReceiverID) and (a.AntennaID = b.AntennaID)
where (a.ReceiverID is NULL or b.ReceiverID is NULL)
and (a.AntennaID IS NULL or b.antennaID is NULL)
select distinct r.ReceiverID, r.ReceiverName, r.receiverdescription
from RFIDReceiver r
inner join #Temp t on r.ReceiverID = t.ReceiverID;
答案 0 :(得分:0)
首先,full join
在第一个查询中毫无意义。您仅从第一张表中选择列,因此您需要这样做。
第二,您可以使用CTE。
第三,通过使用SELECT DISTINCT
条件,您应该可以摆脱EXISTS
。
我建议:
WITH ra AS (
SELECT ra.*
FROM RFIDReceiverAntenna ra
Station s
ON s.ReceiverID = ra.ReceiverID AND
s.AntennaID = ra.AntennaID)
WHERE s.ReceiverID is NULL
)
SELECT r.ReceiverID, r.ReceiverName, r.receiverdescription
FROM RFIDReceiver r
WHERE EXISTS (SELECT 1
FROM ra
WHERE r.ReceiverID = ra.ReceiverID
);
答案 1 :(得分:0)
不需要任何花哨的内容,您只需用内部子查询替换对#temp
的引用,该子查询就包含生成#temp
的查询,例如
select distinct r.ReceiverID, r.ReceiverName, r.receiverdescription
from RFIDReceiver r
inner join (
select
a.ReceiverID,
a.AntennaID,
a.AntennaName
from RFIDReceiverAntenna a
full join Station b ON (a.ReceiverID = b.ReceiverID) and (a.AntennaID = b.AntennaID)
where (a.ReceiverID is NULL or b.ReceiverID is NULL)
and (a.AntennaID IS NULL or b.antennaID is NULL)
) t on r.ReceiverID = t.ReceiverID;
PS:我没有像Gordon那样努力改善整体查询,但确实考虑了他的建议。
答案 2 :(得分:0)
您可以使用CTE代替临时表:
WITH
CTE
AS
(
SELECT
a.ReceiverID,
a.AntennaID,
a.AntennaName
FROM
RFIDReceiverAntenna a
full join Station b
ON (a.ReceiverID = b.ReceiverID)
and (a.AntennaID = b.AntennaID)
where
(a.ReceiverID is NULL or b.ReceiverID is NULL)
and (a.AntennaID IS NULL or b.antennaID is NULL)
)
select distinct
r.ReceiverID, r.ReceiverName, r.receiverdescription
from
RFIDReceiver r
inner join CTE t on r.ReceiverID = t.ReceiverID
;
此查询将返回与使用temp表的原始查询相同的结果,但其性能可能会有所不同;不一定慢,也可以更快。只是您应该注意的事情。