Alter Procedure sp_Member(
@comcode int = 0,
@SubComCode int = 0
)
as begin
set nocount on
If @comcode='0'
begin
select (
select sum(amount)
from tbcoudet
where memcode=tbm.memcode and
expyear=(select max(expyear) from tbexpyear)
and exists (
select itemcode
from tbitem
where comcode=@comcode and
SubComCode=@SubComCode and
itemcode=tbcoudet.itemcode
)
group by memcode,expyear
)'TurnOver', *
into #result from tbmember tbm where can_flag='N'
end
If @subcomcode='0'
begin
select (
select sum(amount)
from tbcoudet
where memcode=tbm.memcode and expyear=(select max(expyear) from tbexpyear)
and exists (
select itemcode
from tbitem
where comcode=@comcode and
itemcode=tbcoudet.itemcode
)
group by memcode,expyear
)'TurnOver', *
into #result from tbmember tbm where can_flag='N'
end
select top 10 * from #result where TurnOver is not null order by TurnOver desc
end
这是我的sql代码,当我要执行存储过程时,我得到错误
There is already an object named '#result' in the database.
谁能告诉我这是什么问题?
答案 0 :(得分:9)
错误是:该名称已经有一个临时表 - 如果它已经存在,请不要重新创建它....
问题在于你选择的方式 - 你有两个地方
select (columns)
into #result
from tbmember tbm
...
第一次,这将创建临时表#result
。第二次,你会得到错误 - 因为它无法创建一个已经存在的表。
因此您需要将代码更改为:
在开头
中明确创建表#result
CREATE TABLE #result ( ...give list of columns and their datatypes here .....)
使用这样的代码插入值:
INSERT INTO #result(colum list)
SELECT (column list)
FROM .......
WHERE .......
该代码将起作用,您将能够在临时表中插入两组数据。
答案 1 :(得分:4)
SELECT ... INTO ...
始终要创建 新 临时表。
而是在过程的顶部创建临时表(使用create table #result (columns)
),然后使用INSERT INTO (columns) SELECT ...
重新编写选择。
我无法写出完整的示例,因为我不知道您的列定义。
即使,当然,只有一个的if
语句是真的,T-SQL解析器相当简单,仍然“看到”两个尝试声明#result
。
顺便说一句,我不确定你为什么写这样的if
陈述:
if @subcomcode='0'
由于@subcomcode
是一个整数,因此最好不要引用0
字面值。
答案 2 :(得分:4)
如果您不确定临时表是否存在,但您确信在下一个语句之前您不需要它以这种方式使用object_id
function:
if object_id('tempdb..#result', 'u') is not null
drop table #result
如果表不存在则不会导致错误,如果表不存在则丢弃它。在我看来,在每个之前使用它是一个很好的做法:
select ... into #temp from ...
答案 3 :(得分:0)
同意在创建新临时表之前删除它是件好事。但是一个简单的解决方法就是在调试这种类型的东西时关闭数据库连接。断开连接 - 擦除所有那些给你。
答案 4 :(得分:0)
我有类似的问题,但这里没有提出的解决方案对我有帮助。我在存储过程中有6个类似于这两个的ifs并且它不会让我改变程序,这没有任何意义,它显然可以工作。在alter procedure上引发相同的错误。我必须在每个if中都有#tbl因为每个if都选择了不同的列而我不想为每个选择制作表。其他选项是动态选择......
我必须让它变得动态(不是全部),就像这样:
IF @Type = '1'
SELECT
col1
INTO #tbl1
FROM Table1
ELSE IF @Type = '2'
SELECT
col1
,col2
INTO #tbl2
FROM Table2
--IF...
DECLARE @sql VARCHAR(MAX) = '
select
*
from #tbl' + @Type
EXEC (@sql)
但在你的情况下,你应该手动创建临时表,因为你使用相同的结构,只是添加值。
如果您懒于创建包含所有列的临时表,则另一种解决方案是:
ALTER PROCEDURE sp_Member (
@comcode INT = 0
, @SubComCode INT = 0
)
AS
BEGIN
SET NOCOUNT ON
SELECT CONVERT(DECIMAL(18, 2), 0) TurnOver
, *
INTO #result
FROM tbmember
WHERE can_flag = 'N'
IF @comcode = '0'
BEGIN
UPDATE r
SET TurnOver = (SELECT SUM(amount)
FROM tbcoudet
WHERE memcode = r.memcode
AND expyear = (SELECT MAX(expyear)
FROM tbexpyear
)
AND EXISTS ( SELECT itemcode
FROM tbitem
WHERE comcode = @comcode
AND SubComCode = @SubComCode
AND itemcode = tbcoudet.itemcode )
GROUP BY memcode
, expyear
)
FROM #result r
END
IF @SubComCode = '0'
BEGIN
UPDATE r
SET TurnOver = (SELECT SUM(amount)
FROM tbcoudet
WHERE memcode = r.memcode
AND expyear = (SELECT MAX(expyear)
FROM tbexpyear
)
AND EXISTS ( SELECT itemcode
FROM tbitem
WHERE comcode = @comcode
AND itemcode = tbcoudet.itemcode )
GROUP BY memcode
, expyear
)
FROM #result r
END
SELECT TOP 10
*
FROM #result
WHERE TurnOver IS NOT NULL
ORDER BY TurnOver DESC
END
答案 5 :(得分:-2)
您正尝试在此过程中创建两次临时表。
在第二个查询中,请不要使用select ... into #result ...
,而是使用insert into #result select ...
,以便它不会再次尝试创建它。
请注意,前缀sp_
表示系统过程,不应用于常规过程。