存储过程老报名为 'myCursor' 的游标不存在、对象名 '#Temgps00520130808' 无效,这我给的入参是2013-8-8

zhaojingjings 2013-08-27 03:23:29
ALTER PROCEDURE [dbo].[P_GetBusLocation]
@Date1 datetime
AS
BEGIN
SET NOCOUNT ON;
declare @VehicleNo nvarchar(50),@VGroupID int,@RouteNumber varchar(200),@TableName varchar(50),@VehicleID bigint ,
@OldVehicleID bigint,@SqlStr1 varchar(1024),@SqlStr2 varchar(1024),@TemTableName varchar(50),@SqlStr3 varchar(1024)
set @TableName = 'gps005' + CONVERT(varchar(20), @Date1, 112)
set @TemTableName = '#Tem' + @TableName
set @SqlStr1 = 'create Table ' + @TemTableName+'(GpsDateTime datetime,VehicleID bigint,VehicleNo nvarchar(50),RouteNumber varchar(200),Flag tinyint
,Longitude decimal(9,6),Latitude decimal(8,6),Speed decimal(4,1),Direction smallint,Mileage bigint
,Position varchar(200),AvgSpeed decimal(4,1),StorageTime datetime)'
exec(@SqlStr1)
set @SqlStr2 = 'insert into '+@TemTableName+' select t1.GpsDateTime,t1.VehicleID,null,null,t1.Flag
,t1.Longitude,t1.Latitude,t1.Speed,t1.Direction,t1.Mileage,t1.Position,t1.AvgSpeed,t1.StorageTime from '+@TableName +' as t1'
exec(@SqlStr2)
set @OldVehicleID = 0
set @SqlStr3 = 'declare myCursor cursor FORWARD_ONLY STATIC for select VehicleID from '+@TemTableName
exec(@SqlStr3)
open myCursor
fetch next from myCursor into @VehicleID
while(@@FETCH_STATUS = 0)
begin
if(@VehicleID != @OldVehicleID)
begin
select @VGroupID = VGroupID,@VehicleNo = VehicleLic from VehicleInfo where VehicleID = @VehicleID
select @RouteNumber = RouteNumber FROM RouteInfo where VGroupID = @VGroupID
exec('update '+@TemTableName+' set VehicleNo = '+@VehicleNo+',RouteNumber = '+@RouteNumber+' where VehicleID = '+@VehicleID)
set @OldVehicleID = @VehicleID
end
fetch next from myCursor into @VehicleID
end
exec('select * from '+ @TemTableName)
close myCursor
deallocate myCursor
END

执行:
DECLARE @return_value int

EXEC @return_value = [dbo].[P_GetBusLocation]
@Date1 = N'2013-8-8'

SELECT 'Return Value' = @return_value

GO

报错:
消息 208,级别 16,状态 0,第 1 行
对象名 '#Temgps00520130808' 无效。
消息 208,级别 16,状态 0,第 1 行
对象名 '#Temgps00520130808' 无效。
消息 16916,级别 16,状态 1,过程 P_GetBusLocation,第 35 行
名为 'myCursor' 的游标不存在。
消息 16916,级别 16,状态 1,过程 P_GetBusLocation,第 38 行
名为 'myCursor' 的游标不存在。
消息 28102,级别 16,状态 1,过程 P_GetBusLocation,第 39 行
批处理执行由于调试器请求而终止。
...全文
405 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
zhaojingjings 2013-08-28
  • 打赏
  • 举报
回复
我就是想用动态的,因为这样可以为自己后面工作省下一些麻烦!但是sqlserver好像不行,不过oralce中可以动态这样搞!
zhaojingjings 2013-08-28
  • 打赏
  • 举报
回复
最后还是用了临时表名固定,但是看着没有自己想的那么完美!
  • 打赏
  • 举报
回复
粗看了一下,你写的存储过程的大概的意思是: 1.创建一个以这个开头的#Temgps临时表。 2.把以这个gps005开头的表的数据,插入到上面创建的临时表中。 3.然后定义了一个游标,取出临时表中的字段VehicleID ,循环遍历, 通过VehicleID 的值作为查询条件,从VehicleInfo表和RouteInfo表中取出相应的值,再更新 上面的临时表 4.最后显示临时表的数据 想了想,要改成完全不用动态语句,好像不太可能,因为gps005表的名称是通过传入的日期参数,动态生成的,但临时表可以随便定义一个:

 set @TableName = 'gps005' + CONVERT(varchar(20), @Date1, 112)
 
 -- 这个临时表的名称,可以随便定义一个
 create Table #TemTableName
 (
  GpsDateTime datetime,VehicleID bigint,VehicleNo nvarchar(50),
  RouteNumber varchar(200),Flag tinyint
  ,Longitude decimal(9,6),Latitude decimal(8,6),
  Speed decimal(4,1),Direction smallint,Mileage bigint
  ,Position varchar(200),AvgSpeed decimal(4,1),
  StorageTime datetime
 )
  
  insert into #TemTableName
  exec('select t1.GpsDateTime,t1.VehicleID,null,null,t1.Flag
       ,t1.Longitude,t1.Latitude,t1.Speed,t1.Direction,t1.Mileage,
       t1.Position,t1.AvgSpeed,t1.StorageTime from ' + @TableName +' as t1') 
  • 打赏
  • 举报
回复
之所以,会报错,找不到对象,是因为你通过exec动态执行语句,而这个语句又创建了一个临时表,这个时候就会有问题。 因为在exec执行动态语句时,是在另一个会话的作用域里执行的,那么执行完成后,确实创建了临时对象, 但结束后,就会释放相应的资源,这时这个临时表,也就被销毁了,所以当存储过程中,再次引用这个临时表时,就会报错。 我觉得,你可以修改一下代码,把动态执行的语句改掉,就可以了。 比如,代码中的动态创建#Temgps00520130808,也是没必要的。
  • 打赏
  • 举报
回复
应该不是output
引用 1 楼 hdhai9451 的回复:
你都没有output参数,你不可那么执行
直接 :

EXEC dbo].[P_GetBusLocation] '2013-8-8'

你要有
SELECT 'Return Value' = @return_value
必须在创建时

ALTER PROCEDURE [dbo].[P_GetBusLocation] 
@Date1 datetime,@xxxx int out put
AS
......
......

go

例如:
CREATE PROC TEST2
  @PA1 INT,
  @PA2 INT,
  @PA3 INT OUTPUT
AS
  SET @PA3 = @PA1 + @PA2
GO

DECLARE @PA4 INT
EXEC TEST2 2,4,@PA4  OUTPUT
SELECT @PA4
应该不是输出参数的问题,因为存储过程的返回值,是SQL Server执行完存储过程,返回的一个状态编码,当然,也可以通过return来返回,比如下面的代码:

if exists(select * from sys.procedures where name = 'ttt')
	drop procedure ttt
go

create procedure dbo.ttt (@v varchar(100))
as

begin
    select null
     
    --return 111 --去掉注释,那么下面执行时会返回:111
end
go





DECLARE	@return_value int

EXEC	@return_value = [dbo].ttt @v = '123'

--输出:0,表示存储过程正常执行,没有错误
SELECT	'Return Value' = @return_value
zhaojingjings 2013-08-27
  • 打赏
  • 举报
回复
看了上面的回答好像知道怎么回事,先自己在整整,有什么不懂继续问,谢谢!
Shawn 2013-08-27
  • 打赏
  • 举报
回复
--楼主写的太乱了。下面给出了,原因和解决方案。自己一一改一下吧:
ALTER PROCEDURE [dbo].[P_GetBusLocation] @Date1 DATETIME
AS 
    BEGIN
        SET NOCOUNT ON;
        DECLARE @VehicleNo NVARCHAR(50) ,
            @VGroupID INT ,
            @RouteNumber VARCHAR(200) ,
            @TableName VARCHAR(50) ,
            @VehicleID BIGINT ,
            @OldVehicleID BIGINT ,
            @SqlStr1 VARCHAR(1024) ,
            @SqlStr2 VARCHAR(1024) ,
            @TemTableName VARCHAR(50) ,
            @SqlStr3 VARCHAR(1024)

        SET @TableName = 'gps005' + CONVERT(VARCHAR(20), @Date1, 112)	--解决方案:由于临时表作用域只针对当前的存储过程.所以直接创建一个固定表名的临时表即可.
		
		create TABLE #Tempgps005
	(GpsDateTime datetime,VehicleID bigint,VehicleNo nvarchar(50),RouteNumber varchar(200),Flag tinyint
	 ,Longitude decimal(9,6),Latitude decimal(8,6),Speed decimal(4,1),Direction smallint,Mileage bigint
		 ,Position varchar(200),AvgSpeed decimal(4,1),StorageTime datetime)

        SET @TemTableName = '#Tempgps005'
        /*SET @SqlStr1 = 'create Table ' + @TemTableName
            + '(GpsDateTime datetime,VehicleID bigint,VehicleNo nvarchar(50),RouteNumber varchar(200),Flag tinyint
 ,Longitude decimal(9,6),Latitude decimal(8,6),Speed decimal(4,1),Direction smallint,Mileage bigint
     ,Position varchar(200),AvgSpeed decimal(4,1),StorageTime datetime)'
        EXEC(@SqlStr1)*/    --#1.根据@TemTableName变量,用EXEC创建的临时表,作用域只在exec()中可见,外面不可见,所以报错

        SET @SqlStr2 = 'insert into ' + @TemTableName	--不可见,所以报错.如果用全局临时表,可见.但要考虑并发问题。
            + ' select t1.GpsDateTime,t1.VehicleID,null,null,t1.Flag
 ,t1.Longitude,t1.Latitude,t1.Speed,t1.Direction,t1.Mileage,t1.Position,t1.AvgSpeed,t1.StorageTime from '
            + @TableName + ' as t1'     
        EXEC(@SqlStr2)   --不可见

        SET @OldVehicleID = 0
        declare myCursor cursor FORWARD_ONLY STATIC  for select VehicleID from #Tempgps005		--这儿也不可见

        OPEN myCursor 
        FETCH NEXT FROM myCursor INTO @VehicleID
        WHILE ( @@FETCH_STATUS = 0 ) 
            BEGIN
                IF ( @VehicleID != @OldVehicleID ) 
                    BEGIN
                        SELECT  @VGroupID = VGroupID ,
                                @VehicleNo = VehicleLic
                        FROM    VehicleInfo
                        WHERE   VehicleID = @VehicleID
                        SELECT  @RouteNumber = RouteNumber
                        FROM    RouteInfo
                        WHERE   VGroupID = @VGroupID
                        EXEC('update '+@TemTableName+' set VehicleNo = '+@VehicleNo+',RouteNumber = '+@RouteNumber+' where VehicleID = '+@VehicleID)
                        SET @OldVehicleID = @VehicleID
                    END
                FETCH NEXT FROM myCursor INTO @VehicleID
            END
        EXEC('select * from '+ @TemTableName) --不可见
        CLOSE myCursor
        DEALLOCATE myCursor
    END
go

--执行:
    DECLARE @return_value INT

    EXEC @return_value = [dbo].[P_GetBusLocation] @Date1 = N'2013-8-8'

    SELECT  'Return Value' = @return_value

GO
Andy__Huang 2013-08-27
  • 打赏
  • 举报
回复
你都没有output参数,你不可那么执行
直接 :

EXEC dbo].[P_GetBusLocation] '2013-8-8'

你要有
SELECT 'Return Value' = @return_value
必须在创建时

ALTER PROCEDURE [dbo].[P_GetBusLocation] 
@Date1 datetime,@xxxx int out put
AS
......
......

go

例如:
CREATE PROC TEST2
  @PA1 INT,
  @PA2 INT,
  @PA3 INT OUTPUT
AS
  SET @PA3 = @PA1 + @PA2
GO

DECLARE @PA4 INT
EXEC TEST2 2,4,@PA4  OUTPUT
SELECT @PA4

22,206

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 疑难问题
社区管理员
  • 疑难问题社区
  • 尘觉
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧