将 Informix 游标转换为 MSSQL 游标

Posted

技术标签:

【中文标题】将 Informix 游标转换为 MSSQL 游标【英文标题】:Convert Informix cursor to MSSQL Cursor 【发布时间】:2017-03-11 02:13:05 【问题描述】:

我在 Informix 数据库中有一个游标,它是函数的一部分,我想将其转换为 MS-SQL 中的游标。

下面是代码:

DECLARE select distinct agentname, agentloginid 
           from selected_agents

            call;
   OPEN cur;
   FETCH cur INTO @l_AgentName, @l_AgentLoginID;
   WHILE @@FETCH_STATUS = 0 BEGIN getAgentLogActivity(@l_AgentName, @l_AgentLoginID, @p_startTime, @p_endTime);
           insert into final_result(Agent_Name, Agent_Login_ID, op1, Login_Time, op2, 
                           Logout_Time, Logout_Reason_Code, Logon_Duration)
            select @l_AgentName, @l_AgentLoginID, op1, logintime, op2, logouttime, reasoncode, duration
                from temp_login_logout;
   FETCH cur INTO @l_AgentName, @l_AgentLoginID;
   end
   CLOSE cur;
   DEALLOCATE cur;

在这种情况下,我发现 Declare 语句存在问题。我知道我必须用下面的方式写这个。

DECLARE cur CURSOR FOR
   SELECT DISTINCT agentname, agentloginid 
           from selected_agents
   OPEN cur;
   FETCH cur INTO @l_AgentName, @l_AgentLoginID;
   WHILE @@FETCH_STATUS = 0 BEGIN getAgentLogActivity(@l_AgentName, @l_AgentLoginID, @p_startTime, @p_endTime);
           insert into final_result(Agent_Name, Agent_Login_ID, op1, Login_Time, op2, 
                           Logout_Time, Logout_Reason_Code, Logon_Duration)
            select @l_AgentName, @l_AgentLoginID, op1, logintime, op2, logouttime, reasoncode, duration
                from temp_login_logout;
   FETCH cur INTO @l_AgentName, @l_AgentLoginID;
   end
   CLOSE cur;
   DEALLOCATE cur;

更新 - selected_agents 声明

DECLARE @selected_agents TABLE (
        agentloginid NVARCHAR(50), 
        agentname NVARCHAR(50),
        agentID INT,
        profileid INT,
        resourcegroupid int,
        dateinactive datetime,
        --filter boolean default 'f',
        rsmid INT,
        teamid INT
    );

现在这里 selected_agents 是我在函数中创建的临时表。

它所说的错误是未声明agentname,agentloginid。顺便说一句,我已经声明了。

谁能帮我改正。

【问题讨论】:

你需要获取下一个但是你在哪里声明了这些变量? 我在这个游标声明之前创建了一个临时表。这个游标和临时表是我拥有的函数的一部分。 介意发布该代码吗?临时表与变量不同。谢谢! 您需要从 selected_agents 更改为 @selected_agents。 @l_AgentName and @l_AgentLoginID 的声明也在哪里。顺便说一句,#trmpTable 是一个临时表,而@table 是一个表变量,它只在事务的生命周期内存在。在删除临时表或关闭连接之前,可以访问临时表。 这就是我声明@l_AgentName 和@l_AgentLoginID 的方式:DECLARE @l_AgentName NVARCHAR(50), @l_AgentLoginID NVARCHAR(50); DECLARE @l_AgentExtension NVARCHAR(50); DECLARE @l_op1 NVARCHAR(1), @l_op2 NVARCHAR(1); DECLARE @l_LoginTime DATETIME2(3), @l_LogoutTime DATETIME2(3), @l_latestSynchedTime DATETIME2(3); DECLARE @l_LogoutReasonCode SMALLINT, @l_selType SMALLINT; DECLARE @l_LogonDuration INT, @l_resCount INT, @l_op INT; declare @l_selValue varchar(4000); 【参考方案1】:

这可能不是 100% 的解决方案,但它有很多 cmets 可以帮助您入门。随时发表评论,让我知道您仍然遇到问题的地方。

DECLARE @selected_agents TABLE (
        agentloginid NVARCHAR(50), 
        agentname NVARCHAR(50),
        agentID INT,
        profileid INT,
        resourcegroupid int,
        dateinactive datetime,
        --filter boolean default 'f',
        rsmid INT,
        teamid INT
    );


/*
Do something here to insert data into @selected_agents
*/

DECLARE @l_AgentName NVARCHAR(50), @l_AgentLoginID NVARCHAR(50); 
DECLARE @l_AgentExtension NVARCHAR(50); 
DECLARE @l_op1 NVARCHAR(1), @l_op2 NVARCHAR(1); 
DECLARE @l_LoginTime DATETIME2(3), @l_LogoutTime DATETIME2(3), @l_latestSynchedTime DATETIME2(3); 
DECLARE @l_LogoutReasonCode SMALLINT, @l_selType SMALLINT;
DECLARE @l_LogonDuration INT, @l_resCount INT, @l_op INT; 
DECLARE @l_selValue varchar(4000);

--Added @ in front of the table name, since it is a table variable you need the @.
DECLARE cur CURSOR FOR
    SELECT DISTINCT agentname, agentloginid 
    from @selected_agents

OPEN cur

--Here we added NEXT FROM to make the syntax correct
FETCH NEXT FROM cur INTO @l_AgentName, @l_AgentLoginID;  

WHILE @@FETCH_STATUS = 0 
BEGIN 

    --Here you seem to be attempting to call a function to potentially set your variables, but this likley isn't happening
    --In another window, try this function and then select the values of your variables to make sure they are being set
    getAgentLogActivity(@l_AgentName, @l_AgentLoginID, @p_startTime, @p_endTime);

    insert into final_result(Agent_Name, Agent_Login_ID, op1, Login_Time, op2,Logout_Time, Logout_Reason_Code, Logon_Duration)
    select 
        @l_AgentName, 
        @l_AgentLoginID, 
        op1, 
        logintime, 
        op2, 
        logouttime, 
        reasoncode, 
        duration
    from 
        temp_login_logout;

--Here we added NEXT FROM to make the syntax correct
FETCH NEXT FROM cur INTO @l_AgentName, @l_AgentLoginID; t

END
CLOSE cur;
DEALLOCATE cur;

【讨论】:

对不起@scsimon,我在你最后的评论中发现了。通过将 @ 添加到声明中,它就起作用了 感谢您返回关闭...所以这是一个解决方案。很高兴知道这一点。 我之前没有看到这个解决方案。所以不知道 没问题,现在你知道了,这才是最重要的。

以上是关于将 Informix 游标转换为 MSSQL 游标的主要内容,如果未能解决你的问题,请参考以下文章

3_11_MSSQL课程_ 游标

MSSQL一种取代游标的方案

MsSQL的游标的综合运用

求助:MSSQL游标 next 后只能取一行数据

将引用游标转换为 pl-sql 中的表类型

如何将自引用的复杂游标转换为更高效的 SQL 代码? CTE、交叉应用还是其他?