You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

将FoxPro转T-SQL:lcCMGTVendor在最终查询中的作用困惑

解惑:Visual FoxPro中lcCMGTVendor的作用及T-SQL转换思路

首先要明确:这段FoxPro代码里的lcCMGTVendor并不是用来过滤数据的,而是作为常量给结果集的provkey字段统一赋值,这是符合这段代码的业务逻辑的,我帮你拆解清楚:

1. lcCMGTVendor的来源

它是从系统配置表dbfs\am_opts中读取的固定配置值:

* 获取病例管理工时的供应商代码
Select op_value ;
FROM dbfs\am_opts ;
WHERE op_code = "CMGT_VENDOR" ;
INTO CURSOR cmgt_vndr
lcCMGTVendor = padr(cmgt_vndr.op_value, 4)

padr(cmgt_vndr.op_value, 4)的作用是把供应商代码补到4位长度(不足的话右侧补空格),对应T-SQL里的LEFT(op_value + SPACE(4), 4)。

2. 代码的核心业务意图

这段代码的目的是:当满足llIncludeCMGT = .T.的条件时,把f_Rpt表中符合筛选规则的工时记录,统一归类到系统配置的CMGT供应商名下——也就是给这些记录的provkey字段强制设置为lcCMGTVendor的值,而不是筛选该供应商自己的记录。

你看到的最终查询:

select lcCMGTVendor as provkey, ;
iif(empty(SQL_F_Rpt.sub_code), "CMGT", SQL_F_Rpt.sub_code) as sub_code, ;
SQL_F_Rpt.keyfld, ;
00000.00 as tot_auth, ;
(SQL_F_Rpt.unit * SQL_F_Rpt.cost) as tot_deliv, ;
SQL_F_Rpt.start_dt as plandt ;
from &SQL_FROM ;
where &SQL_WHERE ;
into cursor pass3

这里的lcCMGTVendor as provkey就是把这个配置值作为常量,给结果集中的每一行都设置相同的provkey,这是业务上的归类需求,逻辑是通顺的。

3. 对应的T-SQL转换思路

第一步:获取配置值

DECLARE @lcCMGTVendor VARCHAR(4);
SELECT TOP 1 @lcCMGTVendor = LEFT(op_value + SPACE(4), 4)
FROM dbfs.am_opts -- 假设已映射为SQL Server表
WHERE op_code = 'CMGT_VENDOR';

第二步:处理llIncludeCMGT的判断逻辑

把FoxPro中的游标判断(_tally > 0)和变量判断转换成T-SQL的BIT变量:

DECLARE @llIncludeCMGT BIT = 0;
-- 对应原代码中判断是否有符合条件的服务
IF EXISTS(SELECT 1 FROM tempsrv WHERE Is_It_Case_Service(sub_code) = 1 AND selected = 1) 
   OR @pcService = 'ALL'
BEGIN
    SET @llIncludeCMGT = 1;
END

-- 再判断是否限定了特定供应商
IF @llIncludeCMGT = 1 AND @pcVendor <> 'ALL'
BEGIN
    -- 检查配置的CMGT供应商是否在选中的供应商列表中
    IF NOT EXISTS(SELECT 1 FROM TempVnd WHERE provkey = @lcCMGTVendor AND Selected = 1)
    BEGIN
        SET @llIncludeCMGT = 0;
    END
END

第三步:执行最终查询(当需要纳入CMGT工时)

IF @llIncludeCMGT = 1
BEGIN
    -- 先构建动态SQL(对应原代码的&SQL_FROM和&SQL_WHERE),或者用静态查询拼接
    DECLARE @SQL_FROM NVARCHAR(MAX) = 'SQL_F_Rpt'; -- 假设SQL_F_Rpt是f_Rpt的别名
    DECLARE @SQL_WHERE NVARCHAR(MAX) = 'SQL_F_Rpt.End_Dt BETWEEN @pdBegin_Date AND @pdEnd_Date 
                                        AND IS_IT_WAIVER(SQL_F_Rpt.Payor, 0) = 0';

    -- 处理付款方筛选
    IF @pcPayor <> 'ALL'
    BEGIN
        SET @SQL_FROM += ', TempPay';
        SET @SQL_WHERE += ' AND SQL_F_Rpt.Payor = TempPay.Payor_CD AND TempPay.Selected = 1';
    END

    -- 处理服务代码筛选
    IF @pcService <> 'ALL'
    BEGIN
        SET @SQL_FROM += ', TempSrv';
        SET @SQL_WHERE += ' AND ISNULL(NULLIF(SQL_F_Rpt.Sub_Code, ''''), ''CMGT'') = TempSrv.Sub_Code 
                            AND TempSrv.Selected = 1';
    END

    -- 执行动态查询
    DECLARE @FullSQL NVARCHAR(MAX) = N'
        SELECT @lcCMGTVendor AS provkey,
               ISNULL(NULLIF(SQL_F_Rpt.sub_code, ''''), ''CMGT'') AS sub_code,
               SQL_F_Rpt.keyfld,
               0.00 AS tot_auth,
               (SQL_F_Rpt.unit * SQL_F_Rpt.cost) AS tot_deliv,
               SQL_F_Rpt.start_dt AS plandt
        FROM ' + @SQL_FROM + '
        WHERE ' + @SQL_WHERE;

    EXEC sp_executesql @FullSQL,
        N'@lcCMGTVendor VARCHAR(4), @pdBegin_Date DATE, @pdEnd_Date DATE',
        @lcCMGTVendor = @lcCMGTVendor,
        @pdBegin_Date = @pdBegin_Date,
        @pdEnd_Date = @pdEnd_Date;
END

总结一下:原FoxPro代码中lcCMGTVendor的作用是给符合条件的工时记录统一设置供应商代码,而不是筛选数据,这个逻辑是业务需求决定的,并没有问题。

内容的提问来源于stack exchange,提问作者Chicken Sandwich No Pickles

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 08:47:56