使用临时表创建函数时出错
Posted
技术标签:
【中文标题】使用临时表创建函数时出错【英文标题】:Error creating function with temporary tables 【发布时间】:2021-12-13 02:14:44 【问题描述】:我正在创建一个包含临时表的函数,将函数与临时表一起使用对我来说有点困难,我完全不知道函数中是否允许它,因为我是新函数.
我要创建的函数如下:
CREATE FUNCTION FunctionTest (
@Anio int=null,
@Mes int=Null,
@Meses int=6
)
RETURNS @Tabla TABLE (
AnioMes INT,
Viaje VARCHAR(30),
IdPorte INT,
Carga VARCHAR(20),
Peso numeric(32, 16)
)
AS
BEGIN
Declare @AnioMes varchar(8),
@AnioMes6 varchar(8)
if @Anio is null
Select @Anio = YEAR(GETDATE()),
@Mes = MONTH(GETDATE())
Select @AnioMes = (case when @Mes=12 then @Anio+1 else @Anio end *100 + Case when @Mes=12 then 1 else @Mes+1 end)*100 + 1
Select @AnioMes6 = convert(varchar(8), DATEADD(mm, -@Meses, @AnioMes), 112 )
INSERT INTO @Tabla (AnioMes,Viaje,IdPorte,Carga,Peso)
SELECT year(cpsj.Delivery)*100 + MONTH(cpsj.Delivery) as AnioMes,
tr.TId as Viaje,
cpsj.PId as IdPorte,
CASE WHEN tr.Load = 1 THEN 'CARGADO'
WHEN tr.Load = 2 THEN 'VACIO'
END as Carga,
cpsj.Weight as Peso,
into #Temp
FROM BDNEW.dbo.CENPACKSTOREJOIN cpsj
inner join TRANS tr on cpsj.ipId = tr.ipId
inner join OPERA oper on tr.OId = oper.OId
WHERE cpsj.Id = 'ID001'
AND tr.Area = 'lost'
AND tr.Status = 2
GROUP BY cpsj.Delivery, cpsj.IName
ORDER BY cpsj.ipId
if @AnioMes6 < '20160101'
insert #Temp
SELECT Year(cpsj.Delivery)*100 + MONTH(cpsj.Delivery) as AnioMes,
tr.TId as Viaje,
cpsj.PId as IdPorte,
CASE WHEN tr.Load = 1 THEN 'CARGADO'
WHEN tr.Load = 2 THEN 'VACIO'
END as Carga,
cpsj.Weight as Peso,
FROM BDOLD.dbo.CENPACKSTOREJOIN cpsj
inner join TRANS tr on cpsj.ipId = tr.ipId
inner join OPERA oper on tr.OId = oper.OId
WHERE cpsj.Id = 'ID001'
AND tr.Area = 'lost'
AND tr.Status = 2
GROUP BY cpsj.Delivery, cpsj.IName
ORDER BY cpsj.ipId
Delete #Temp
where viaje in (
select MAX(Viaje)
from #Temp
group by IdPorte
having COUNT(IdPorte) > 1
)
Select AnioMes,
Viaje,
IdPorte,
Carga,
Peso,
from #Temp
GROUP BY AnioMes,IdPorte Viaje, Carga, Peso
ORDER BY AnioMes,IdPorte
RETURN
END
如果你注意到我正在使用一个名为 #Temp
的临时表。
在尝试编译函数时出现错误消息,我收到以下错误消息:
无法从函数内访问临时表。
这就是为什么我前面提到如果你真的可以在函数中使用临时表。
感谢任何可以指导我如何处理此功能的人。
【问题讨论】:
我正试图绕过INSERT INTO @Tabla ... SELECT ... INTO #Temp
...请解释为什么你认为你需要@Tabla
和#Temp
在这里?
INSERT INTO @Tabla
是我为我的函数创建的东西,我真的不知道是否应该在那里使用它,或者我是否应该对语法进行一些修改
你应该只是INSERT INTO @Tabla
,然后更新/删除@Tabla
,然后你修改后@Tabla
的内容就是函数返回的内容。
@AaronBertrand 您可以根据您的评论添加新答案,但要考虑到我在问题中发布的语法
@AaronBertrand 你知道you spend loads of time answering a question 和 OP 刚刚发布另一个问题,表明他们完全无视你的建议......非常伤人,TBH
【参考方案1】:
你要么使用
INSERT INTO @Tabla (AnioMes,Viaje,IdPorte,Carga,Peso)
SELECT year(cpsj.Delivery)*100 ...
或者
SELECT year(cpsj.Delivery)*100 ...
INTO #Temp
FROM...
不是两者:
INSERT INTO @Tabla (AnioMes,Viaje,IdPorte,Carga,Peso)
SELECT year(cpsj.Delivery)*100 ...
INTO #Temp
FROM...
而且你不能在函数中使用临时表。
【讨论】:
如果我不使用 INSERT INTO @Table 我会收到错误消息Invalid use of a side-effecting operator 'SELECT' within a function
这是因为您不能只选择结果集而不将其分配给变量。见:***.com/questions/13603111/…以上是关于使用临时表创建函数时出错的主要内容,如果未能解决你的问题,请参考以下文章