1

我创建了一个使用游标的 SQL Server 存储过程,并创建了一个 ASP.NET 方法来执行该过程。我正在使用SqlDataReaderandwhile(reader.Read())来读取值。问题是存储过程中的游标返回很多行,但该方法只读取第一条记录。任何人都可以帮忙吗?

存储过程:

create procedure [dbo].[GetMenusUserGroupCanView] 
(
  @UserGroupID int
 ,@LanguageID int
) as begin

    declare @MenuID int

    declare @Title varchar(255)

    declare db_cursor cursor for
    (
        select MenuID
        from TrioGate.dbo.Sys_UserGroupMenus
        where UserGroupID=@UserGroupID and ViewFlag='true'
    )

    open db_cursor  

    fetch next from db_cursor into @MenuID  

    while @@fetch_status = 0 begin  

        select 
         Sys_Menus.MenuID
        ,Sys_Menus.ParentMenuID
        ,Sys_Menus.DescriptionLabelID
        ,Sys_Menus.TitleLabelID
        ,Sys_Menus.TooltipLabelID
        ,Sys_Menus.[Icon]
        ,Sys_Menus.[MenuName]
        ,Sys_Menus.[MenuTypeID] as MenuType
        ,[dbo].[Get_ParentMenu_Name](Sys_Menus.ParentMenuID) as ParentMenuName
        ,[dbo].[Get_Label_Description](Sys_Menus.TitleLabelID,1) as Title
        ,[dbo].[Get_Label_Description](Sys_Menus.TooltipLabelID,1) as Tooltip
        ,[dbo].[Get_Label_Description](Sys_Menus.DescriptionLabelID,1) as [Description]
        ,Sys_Menus.[MainTableName] as [Table]
        ,Sys_Menus.[Seq],Sys_Menus.[MenuPath],Sys_Menus.ActivateLog,Sys_Menus.MenuID 
        from Sys_Menus 
            left join Sys_LabelDetails
            on Sys_Menus[TitleLabelID] = Sys_LabelDetails[LabelID]
        where Sys_LabelDetails.LanguageID = @LanguageID 
        and MenuID = @MenuID     

        fetch next from db_cursor into @MenuID  

    end

    close db_cursor  
    deallocate db_cursor 

end

方法:

public List<Menu> GetMenusUserGroupCanView(int UserGroupID, int LanguageID)
{
    List<Menu> list = new List<Menu>();
    SqlCommand cmd = new SqlCommand("GetMenusUserGroupCanView ", Connection);
    cmd.CommandType = CommandType.StoredProcedure;
    cmd.Parameters.AddWithValue("@UserGroupID", UserGroupID);
    cmd.Parameters.AddWithValue("@LanguageID", LanguageID);
    try
    {

        Connection.Open();
        SqlDataReader reader = cmd.ExecuteReader();
        while (reader.Read())
        {
            Menu entry = new Menu();
            entry.MenuID = (int)reader["MenuID"];
            entry.ParentMenuID = (int)reader["ParentMenuID"];
            entry.ActivateLog = (bool)reader["ActivateLog"];
            entry.Description = reader["Description"].ToString();
            entry.DescriptionLabelID = (int)reader["DescriptionLabelID"];
            entry.Icon = (byte[])reader["Icon"];
            entry.MainTableName = reader["Table"].ToString();

            entry.MenuName = reader["MenuName"].ToString();
            entry.MenuPath = reader["MenuPath"].ToString();
            entry.MenuTypeID = reader["MenuType"].ToString();
            entry.ParentMenuName = reader["ParentMenuName"].ToString();
            entry.Seq = (int)reader["Seq"];

            entry.Title = reader["Title"].ToString();
            entry.TitleLabelID = (int)reader["TitleLabelID"];
            entry.Tooltip = reader["Tooltip"].ToString();
            entry.ToolTipLabelID = (int)reader["ToolTipLabelID"];
            list.Add(entry);
        }

    }
    catch { }
    finally
    {
        Connection.Close();
    }
    return list;
}     
4

1 回答 1

5

循环的每次迭代都会执行一次选择。因此,您得到的不是一组多条记录,而是多

选择你的命运:

A.(治疗症状):在结果集之间推进你的读者IDataReader.NextResult()

B.(解决问题):不需要那个光标;改用连接

select
 * /* dump your columns back in here */
from Sys_UserGroupMenus as g
    join Sys_Menus as m
        join Sys_LabelDetails as d
        on d.LabelID = m.TitleLabelID
        and d.LanguageID = @LanguageID
    on m.MenuID = g.MenuID
where g.UserGroupID = @UserGroupID
and g.ViewFlag = 'true'
于 2013-05-13T19:03:54.240 回答