以文本方式查看主题

-  Foxtable(狐表)  (http://foxtable.net/bbs/index.asp)
--  专家坐堂  (http://foxtable.net/bbs/list.asp?boardid=2)
----  储存过程使用的全局临时表,前端调用总提示错误  (http://foxtable.net/bbs/dispbbs.asp?boardid=2&id=186620)

--  作者:happyft
--  发布时间:2023/5/16 9:47:00
--  储存过程使用的全局临时表,前端调用总提示错误
储存过程如下:
--计算各面板任务记录数
ALTER PROCEDURE [dbo].[usp_alert20]
    (
      @Rotype INT ,
      @RoleAll NVARCHAR(800) ,
      @RoleSwtx NVARCHAR(800) ,
      @count INT OUTPUT   
    )
AS
    BEGIN
        SET NOCOUNT ON;
        IF OBJECT_ID(\'tempdb..##temp1\') IS NOT NULL
            DROP TABLE ##temp1;         
        IF OBJECT_ID(\'tempdb..##temp2\') IS NOT NULL
            DROP TABLE ##temp2;    
        
        DECLARE @sql2 NVARCHAR(MAX);
        IF @Rotype = 1  --系统管理员加载事务提醒中所有数据
            BEGIN
           --将数据存入临时表   
                SET @sql2 = \'   
SELECT  a.*
INTO    ##temp1
FROM    ( SELECT    a.* ,
b.Fname AS 流程名称 
  FROM      dbo.事务提醒 a
LEFT JOIN dbo.ftbSet b ON a.单据名称 = b.tbN
  AND a.sys_Fbh = b.Fid
) a\';

                EXEC sp_executesql @sql2;
                --查询返回可处理记录数
                SELECT  @count = COUNT(*)
                FROM    ##temp1;
            END; 
        ELSE
            IF @Rotype = 2
                BEGIN
      --将用户有权处理的表单及流程存入全局临时表
                    SET @sql2 = \'  
SELECT  a.*
INTO    ##temp2
FROM    (   
SELECT  tbN,Fid
FROM    ftbSet
WHERE sqRole like \' + @RoleAll
                        + \') a   
                          
              --将事务提醒中用户有权处理的数据存入临时表   
SELECT  a.*
INTO    ##temp1
FROM    ( SELECT    a.* ,
b.Fname AS 流程名称 
  FROM      dbo.事务提醒 a
LEFT JOIN dbo.ftbSet b ON a.单据名称 = b.tbN
  AND a.sys_Fbh = b.Fid
  WHERE     EXISTS ( SELECT *
FROM   ##temp2 c
WHERE  c.tbN = a.单据名称
AND c.Fid = a.sys_Fbh )
AND (a.接收人 = \'\'自动导入\'\' OR a.接收人 LIKE \'
                        + @RoleSwtx + \')
) a \';
                    EXEC sp_executesql @sql2;
                    --查询返回可处理记录数
                    SELECT  @count = COUNT(*)
                    FROM    ##temp1;
                END;

               
        SET NOCOUNT OFF;
        
    END;

ft前端调用

\'计算用户可处理的待处理记录数

Dim cmd As new SQLCommand

cmd.ConnectionName = Mydata

cmd.CommandText = "Exec usp_alert20 ?,?,?,? output" 

cmd.Parameters.Add("@角色类型",Rotype) \'输入参数

cmd.Parameters.Add("@所有角色",Role_All) \'输入参数

cmd.Parameters.Add("@事务角色",Role_swtx) \'输入参数

cmd.Parameters.Add("@返回值", 0, True) \'输出参数

cmd.ExecuteNonQuery

count = cmd.Parameters("@返回值")

pg.text = pg.name & "(" & count & ")"


出错提示:

NET Framework 版本:4.0.30319.42000

Foxtable 版本:2022.8.18.1

错误所在事件:

详细错误信息:

对象名 \'##temp1\' 无效。

提供程序无法确定 Int32 值。例如,该行刚刚创建,未提供 Int32 列的默认值,并且使用者尚未设置新 Int32 值。


谢谢!

--  作者:有点蓝
--  发布时间:2023/5/16 9:59:00
--  
首先,临时表是在这里【EXEC sp_executesql @sql2;】动态创建的,只能在这个SQL里面使用,外部是不知道有这么个临时表的。

其次,Foxtable使用的oledb驱动不支持存储过程里使用临时表

--  作者:HappyFt
--  发布时间:2023/5/16 11:00:00
--  
  EXEC sp_executesql @sql2;
--查询返回可处理记录数
 SELECT  @count = COUNT(*)
FROM    ##temp1;
我用上面一句将全局临时表的记录数查询给@count这个output 的变量返回给前端应该没有错吧?
是不是就是第二个原因导致出错的,但因为前面传入的参数无固定值我又必须要用动态sql才能查询,有什么解决办法吗?
谢谢!

--  作者:有点蓝
--  发布时间:2023/5/16 11:04:00
--  
虽然第二个原因导致了Foxtable无法使用带临时表的存储过程,但是不会出错的,只是无法返回数据。

现在这个错误明显是存储过程自己的错误。先到SqlServer的客户端ssms里测试通过了再说把......不管测试通过了也没用,Foxtable也用不了

--  作者:HappyFt
--  发布时间:2023/5/16 12:13:00
--  
Foxtable使用的oledb驱动不支持存储过程里使用临时表?
会影响哪些调用?
不能象一楼那样的参数化调用?还是其他方面,谢谢!


--  作者:有点蓝
--  发布时间:2023/5/16 13:28:00
--  
就是存储过程里不能使用临时表啊
--  作者:HappyFt
--  发布时间:2023/5/16 13:39:00
--  
没明白,我的项目中很多储存过程都用了临时表,也没有出个错啊,
下面这个联合查询就是储存过程中最后一段调用前面生成的多个临时表的数据,都没有出过错啊
 SELECT  a.产品编码 ,
                b.品名 ,
                b.规格 ,
                b.产品类别 ,
                a.单位用量 ,
                a.计量单位 ,
                e.待领用量 ,
                c.库存数量 ,
                d.采购在线 ,
                f.待采购量 ,
                ISNULL(e.待领用量, 0) - ISNULL(c.库存数量, 0) - ISNULL(d.采购在线, 0)
                - ISNULL(f.待采购量, 0) AS 需请购量
        FROM    #cte a
                LEFT JOIN 产品编码 b ON a.产品编码 = b.产品编码
                LEFT JOIN #kc c ON c.产品编码 = a.产品编码
                LEFT JOIN #online d ON d.产品编码 = a.产品编码
                LEFT JOIN #out e ON e.产品编码 = a.产品编码
                LEFT JOIN #qg f ON f.产品编码 = a.产品编码
        ORDER BY a.产品编码;
目前就一楼那个储存过程因为用了动态sql出错,其他都没有出过错唉!是我理解错了吗?


--  作者:有点蓝
--  发布时间:2023/5/16 13:43:00
--  
那可能您中彩了,Foxtable一向都不支持在存储过程里返回临时表的数据的。我不理解为什么您的可以使用

另外代码都是有程序域的,在动态SQL里执行的临时表,只能在动态SQL里使用,动态SQL之外是来一个程序域,无法知道动态SQL里创建里创建了什么变量,所以是无法使用的。考虑先使用create语法创建好临时表,然后在动态SQL里给先创建好的临时表赋值