【达梦数据库】函数传参问题复现

【达梦数据库】函数传参问题复现

在处理问题的过程中,客户反馈在当前版本下函数参数名和函数中引用表的列名相同的话,会报错,请求我们确认是否为BUG。复现过程如下:

1、创建基础表数据

--版本:8.1.3.100--创建表kcrp_dict_trans
CREATE TABLE kcrp_dict_trans(
item_value VARCHAR(255),
src_sys_no VARCHAR(255),  
dict_type VARCHAR(255),  
dict_id VARCHAR(255) 
);

--插入数据
insert into "kcrp_dict_trans"(item_value,src_sys_no,dict_type,dict_id)
values('abc',1,2,3);
insert into "kcrp_dict_trans"(item_value,src_sys_no,dict_type,dict_id)
values('def',4,5,6);
--提交
COMMIT;
--查询
select * from "kcrp_dict_trans";

2、函数参数名和引用的表的字段名相同

------------创建函数1:函数参数名和引用的表的字段名相同------------
CREATE OR REPLACE FUNCTION dict_kcrp(  
    src_sys_no IN VARCHAR,  
    dict_type IN VARCHAR,  
    dict_id IN VARCHAR  
) RETURN VARCHAR 
AS  
    -- 声明密码变量,指定长度  
    v_pass VARCHAR(255);  
BEGIN  
    v_pass := ''; 
    
    SELECT item_value INTO v_pass  
    FROM kcrp_dict_trans A  
    WHERE A.src_sys_no = src_sys_no   
    AND A.dict_type = dict_type  
    AND A.dict_id = dict_id;  
  
    -- 返回查询到的密码  
    RETURN v_pass;  
END;

------------查询函数1------------
select "dict_kcrp"(123) from DUAL;

--结果
报错
select "dict_kcrp"(123) from dual;
执行失败(语句1)
-7046: SELECT INTO中包含多行数据
-7046: dict_kcrp line 16 

3、函数参数名和引用的表的字段名不同

------------------------------------------------
------------创建函数2:函数参数名和引用的表的字段名不相同------------
CREATE OR REPLACE FUNCTION dict_kcrp1(  
    p_src_sys_no IN VARCHAR,  
    p_dict_type IN VARCHAR,  
    p_dict_id IN VARCHAR  
) RETURN VARCHAR 
AS  
    -- 声明密码变量,指定长度  
    v_pass VARCHAR(255);  
BEGIN  
    v_pass := ''; 
    
    SELECT item_value INTO v_pass  
    FROM kcrp_dict_trans A  
    WHERE A.src_sys_no = p_src_sys_no   
    AND A.dict_type = p_dict_type  
    AND A.dict_id = p_dict_id;  
  
    -- 返回查询到的密码  
    RETURN v_pass;  
END;

------------查询函数2------------
SELECT "dict_kcrp1"(1,2,3)from DUAL;
--结果:abc

SELECT "dict_kcrp1"(4,5,6)from DUAL;
--结果:def

4、其他版本

--复现140版本,出现同样的问题:--03134284172-20240527-229704-20093 Pack5
--复现162版本,出现同样的问题:--03134284172-20240527-229704-20093 Pack5
--oracle上复现,出现同样的问题

5、结论:

--为了更加明确和避免潜在的命名冲突,建议区分参数和列名规避--
CREATE OR REPLACE FUNCTION dict_kcrp(    
    p_src_sys_no IN VARCHAR,  -- 使用前缀 p_ 来区分参数和列名  
    p_dict_type IN VARCHAR,   -- 同上  
    p_dict_id IN VARCHAR      -- 同上  
) RETURN VARCHAR   
AS    
    -- 声明密码变量,指定长度    
    v_pass VARCHAR(255);    
BEGIN    
    -- 初始化变量为 NULL 或空字符串(在这个场景下两者都可以,因为 SELECT INTO 会覆盖它)  
    v_pass := '';   
      
    -- 使用明确的别名来引用表列,尽管在这个例子中不是必需的  
    SELECT item_value INTO v_pass    
    FROM kcrp_dict_trans A    
    WHERE A.src_sys_no = p_src_sys_no  -- 使用参数别名 p_src_sys_no  
    AND A.dict_type = p_dict_type      -- 使用参数别名 p_dict_type  
    AND A.dict_id = p_dict_id;         -- 使用参数别名 p_dict_id  
    
    -- 返回查询到的密码,如果没有查询到结果,则 v_pass 将保持为 ''  
    RETURN v_pass;    
END;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值