【问题标题】:Select returns 0 rows in a cursor and right number of rows in manual running选择在光标中返回 0 行,在手动运行中返回正确的行数
【发布时间】:2010-11-25 14:06:53
【问题描述】:

我有这个游标声明:

     DECLARE CursorArticulo CURSOR FOR
        SELECT HstAt.IdArticulo, SUM(HstAt.Cantidad) As SumaCantidad, 
            HstAt.Precio 
        FROM HstArticulosTickets hstAT INNER JOIN HstTickets HstT 
             ON hstAT.IdTicket=hstT.IdTicket
        WHERE hstT.NumUsuarioEmisor=@UsuarioAct
                  AND HstT.NumZona=@ZonaAct
              AND DATEDIFF(day,@par_Fecha,HstT.FechaHoraTicket)=0
    GROUP BY IdArticulo, Precio
    ORDER BY IdArticulo

参数@UsuarioAct 和@ZonaAct 是从另一个Cursor 获得的。 @par_Fecha 参数是存储过程的输入参数。

如果我运行存储过程,在这个游标中我永远不会得到一行。永远不会进入典型的 WHILE @@FETCH_STATUS = 0 循环。

我尝试在查询分析器中复制选择代码并用值替换参数,然后我得到了正确的行。

我在 SQL Server 2008 中运行它。

为什么会这样?

谢谢大家。

编辑:

完整的存储过程代码:

改变程序 [dbo].[paCreTablaHojaDeCajaMA] @par_Fecha 作为日期时间 作为 开始 -- 添加了 SET NOCOUNT ON 以防止额外的结果集 -- 干扰 SELECT 语句。 设置无计数;

DELETE FROM dbo.TmpDetalleHojaDeCajaDiaria
DELETE FROM dbo.TmpMaestraHojaDeCajaDiaria

INSERT INTO TmpMaestraHojaDeCajaDiaria 
    (NumUsuario, ZonaAsignada, TipoUsuario, NumPDA, ImporteUsuarioZona)
SELECT
    hstZA.NumUsuario, hstZA.NumZonaAsignada, 
       (SELECT TipoUsuario FROM Usuarios U WHERE U.NumUsuario=hstZA.NumUsuario) AS TipoUsuario,
       (SELECT NumPDA FROM Usuarios U WHERE U.NumUsuario=hstZA.NumUsuario) AS NumPDA,
       (SELECT SUM(hstT.ImporteTotal) FROM HstTickets hstT 
            WHERE hstT.NumUsuarioEmisor=hstZA.NumUsuario
            AND hstT.NumZona=hstZA.NumZonaAsignada
            AND DATEDIFF(day,hstZA.Fecha,HstT.FechaHoraTicket)=0) AS ImporteUsuarioZona
FROM hstZonasAsignadas hstZA
WHERE DATEDIFF(day,hstZA.Fecha,@par_Fecha)=0
ORDER BY NumUsuario


DECLARE @UsuarioAct NCHAR(4)
DECLARE @ZonaAct SMALLINT
DECLARE @IdUnicoAct INTEGER
DECLARE @IdArticulo INTEGER
DECLARE @NombreArticulo NCHAR(50)
DECLARE @PrecioUd MONEY
DECLARE @SumaCantidad INTEGER

DECLARE CursorMaestra CURSOR FOR
     SELECT NumUsuario, ZonaAsignada, IdUnico FROM TmpMaestraHojaDeCajaDiaria
     ORDER BY NumUsuario

OPEN CursorMaestra

PRINT 'CURSOR ABIERTO'

-- Vamos a por el primero
FETCH NEXT FROM CursorMaestra INTO @ZonaAct, @UsuarioAct, @IdUnicoAct

WHILE @@FETCH_STATUS = 0
BEGIN

     PRINT @ZonaAct
     PRINT @UsuarioAct

     DECLARE CursorArticulo CURSOR FOR
        (SELECT HstAt.IdArticulo, SUM(HstAt.Cantidad) As SumaCantidad, HstAt.Precio 
        FROM HstArticulosTickets hstAT INNER JOIN HstTickets HstT 
             ON hstAT.IdTicket=hstT.IdTicket
        WHERE hstT.NumUsuarioEmisor=@UsuarioAct
                              AND HstT.NumZona=@ZonaAct
                              AND DATEDIFF(day,@par_Fecha,HstT.FechaHoraTicket)=0
        GROUP BY IdArticulo, Precio)

     OPEN CursorArticulo
     PRINT '   CURSOR ABIERTO'

     -- Vamos a por el primero
     FETCH NEXT FROM CursorArticulo INTO @IdArticulo, @SumaCantidad, @PrecioUd

     PRINT @@FETCH_STATUS
     WHILE @@FETCH_STATUS = 0
     BEGIN

         SELECT @NombreArticulo = NombreArticulo FROM Articulos
             WHERE IdArticulo = @IdArticulo

         PRINT @NombreArticulo

         INSERT INTO TmpDetalleHojaDeCajaDiaria
             (NumUsuario, ZonaAsignada, IdArticulo, NombreArticulo, PrecioUD, CantidadZonaUsuario, IdUnicoMaestra)
         VALUES
             (@UsuarioAct, @ZonaAct, @IdArticulo, @NombreArticulo, @PrecioUd, @SumaCantidad, @IdUnicoAct)

         FETCH NEXT FROM CursorArticulo INTO @IdArticulo, @SumaCantidad, @PrecioUd



     END

     CLOSE CursorArticulo
     DEALLOCATE CursorArticulo

     PRINT '   CURSOR CERRADO'

     FETCH NEXT FROM CursorMaestra INTO @ZonaAct, @UsuarioAct, @IdUnicoAct
END

CLOSE CursorMaestra
DEALLOCATE CursorMaestra

PRINT 'CURSOR CERRADO'

结束

【问题讨论】:

  • 您能否提供更多存储过程 - 例如,您如何读取和关闭光标?

标签: sql sql-server database select


【解决方案1】:

你可以尝试为选择添加括号

DECLARE CursorArticulo CURSOR FOR ( 选择 HstAt.IdArticulo, SUM(HstAt.Cantidad) 作为 SumaCantidad, HstAt.Precio FROM HstArticulosTickets hstAT INNER JOIN HstTickets HstT ON hstAT.IdTicket=hstT.IdTicket 其中 hstT.NumUsuarioEmisor=@UsuarioAct AND HstT.NumZona=@ZonaAct AND DATEDIFF(day,@par_Fecha,HstT.FechaHoraTicket)=0 GROUP BY IdArticulo, Precio 由 IdArticulo 订购 )

变量@UsuarioAct 和@ZonaAct 是否被填充?您可以尝试将其替换为您尝试手动查询时的那个吗?

【讨论】:

  • 是的,变量@UsuarioAct 和@ZonaAct 正在填充正确的值。我要试试括号...
  • 很好奇:当我添加括号时,我得到一个“ORDER 附近的语法错误”,所以我取消了 ORDER BY IdArticulo,但我得到了相同的 0 行。在手动运行中有一个 ORDER BY 并且我没有收到任何错误(重复:使用正确的 4 个返回行)。
  • 是否可以发布整个查询,包括生成 @UsuarioAct 和 @ZonaAct 的另一个游标?似乎您正在尝试嵌套光标,以下是我引用的链接之一rpbouman.blogspot.com/2005/10/nesting-mysql-cursor-loops.html
  • 至 Umesh:SQL Server 中允许嵌套游标。文档中甚至还有一个示例。
【解决方案2】:

变量@UsuarioAct 和@ZonaAct 是否被声明为正确的数据类型?

也许隐式转换正在巧妙地改变数据的含义?

【讨论】:

    【解决方案3】:

    我找到了!

    如果你阅读了外部游标声明:

    DECLARE CursorMaestra CURSOR FOR 从 TmpMaestraHojaDeCajaDiaria 中选择 NumUsuario、ZonaAsignada、IdUnico 由 NumUsuario 订购

    顺序是 NumUsuario、ZonaAsignada、IdUnico

    但后来,在第一个 FETCH 中:

    从 CursorMaestra 获取下一个到 @ZonaAct、@UsuarioAct、@IdUnicoAct

    我改变了顺序,正确的是@UsuarioAct、@ZonaAct、@IdUnicoAct。

    所以,用户 (UsuarioAct) 和区域 (ZonaAct) 数据是错误的。

    谢谢大家的提示。

    【讨论】:

      【解决方案4】:

      由于您最初在内部游标上得到 @@FETCH_STATUS = -1,我会得出结论,您的 SELECT 语句不返回任何行。您确实提到在执行查询时会得到结果,但请尝试以下操作:第一个 BEGIN ... END 块的内容仅替换为以下代码,看看您是否确实获得了结果集:

      SELECT      HstAt.IdArticulo, SUM(HstAt.Cantidad) As SumaCantidad, HstAt.Precio 
      FROM        HstArticulosTickets hstAT 
      INNER JOIN  HstTickets HstT 
              ON  hstAT.IdTicket=hstT.IdTicket
      WHERE       hstT.NumUsuarioEmisor=@UsuarioAct
              AND HstT.NumZona=@ZonaAct
              AND DATEDIFF(day,@par_Fecha,HstT.FechaHoraTicket)=0
      GROUP BY    IdArticulo, Precio
      

      并检查您是否得到任何结果。如果不这样做,则删除 WHERE 子句中的一些过滤器...

      【讨论】:

      • 像啤酒一样免费...只要您不违反团队的指导标准
      猜你喜欢
      • 2017-09-15
      • 2011-08-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-01-21
      • 2015-04-15
      • 1970-01-01
      • 2015-07-11
      相关资源
      最近更新 更多