当前位置: 首页 > news >正文

HANA如何在存储过程里执行动态SQL

业务场景需求:

在HANA里如何实现动态的SQL控制,比如需要多个单据里,实现某个自定义字段不允许重复

一般的写法是需要在每个业务单据里加对应的存储过程控制,这样的话,需要在每个业务单据里进行控制,SQL维护量比较大,尝试想看看有没有一段统一的批量动态SQL,可以实现自动根据object_type 来实现动态查询对应的SAP表。

比如:

IF :object_type = '13' AND :transaction_type = N'A' THEN

	SELECT COUNT(*) INTO SAP_COUNT FROM
	(
	SELECT COUNT(A."U_ID") FROM
	(
	SELECT DISTINCT T1."DocEntry",T1."U_ID" 
	FROM OINV T0
	INNER JOIN INV1 T1 ON T0."DocEntry" = T1."DocEntry"
	WHERE 
	T0."CANCELED" = 'N'
	AND IFNULL(T1."U_ID",'') IN (SELECT "U_ID" FROM INV1 WHERE "DocEntry" = list_of_cols_val_tab_del)
	) A
	GROUP BY A."U_ID"
	HAVING COUNT(*) > 1
	)
	;

	IF SAP_COUNT > 0
		THEN
		error := 1;
		error_message := '此ID已存在,不允许重复传入SAP,请核实!';
	END IF;
END IF;

实现方案:

尝试在存储过程里定义变量,然后通过变量承接构建的SQL查询,最后使用EXECUTE IMMEDIATE执行构建好的SQL。此方法可以省去每当需要控制一个单据的时候,就重新写一段重复值,控制的SQL,只需要把对应的object_type 和表名加进去即可,如果不需要进行控制了,也可以直接取消对应的object_type 和表名。

SQL如下:

ALTER PROCEDURE SBO_SP_TransactionNotification
(
    in object_type nvarchar(30),                -- SBO Object Type
    in transaction_type nchar(1),           -- [A]dd, [U]pdate, [D]elete, [C]ancel, C[L]ose
    in num_of_cols_in_key int,
    in list_of_key_cols_tab_del nvarchar(255),
    in list_of_cols_val_tab_del nvarchar(255)
)
LANGUAGE SQLSCRIPT
AS
-- Return values
error  int;             -- Result (0 for no error)
error_message nvarchar (200);       -- Error string to be displayed
SAP_COUNT int;    --定义SAP计数变量
v_sql NVARCHAR(1000);    --定义构建SQL变量
table1 NVARCHAR(50);    --定义表1变量
table2 NVARCHAR(50);    --定义表2变量

begin

error := 0;
error_message := N'Ok';
-----------------------------------------------------------------------------------------
IF (
	object_type = '15' OR --销售交货
	object_type = '16' OR --销售退货
	object_type = '13' OR --应收发票
	object_type = '14' OR --应收贷项凭证
	object_type = '20' OR --采购收货
	object_type = '21' OR --采购退货
	object_type = '18' OR --应付发票
	object_type = '19' OR --应付贷项凭证
	object_type = '59' OR --收货
	object_type = '60' OR --发货
	object_type = '67' OR --库存转储
	object_type = '10000071' OR --库存盘点过账
	object_type = '202' --生产订单
	)
	AND transaction_type IN ('A')
	THEN
	
	--确定主表,然后插入到table1里
	SELECT
	CASE :object_type
	WHEN 15 THEN 'ODLN' --销售交货
	WHEN 16 THEN 'ORDN' --销售退货
	WHEN 13 THEN 'OINV' --应收发票
	WHEN 14 THEN 'ORIN' --应收贷项凭证
	WHEN 20 THEN 'OPDN' --采购收货
	WHEN 21 THEN 'ORPD' --采购退货
	WHEN 18 THEN 'OPCH' --应付发票
	WHEN 19 THEN 'ORPC' --应付贷项凭证
	WHEN 59 THEN 'OIGN' --收货
	WHEN 60 THEN 'OIGE' --发货
	WHEN 67 THEN 'OWTR' --库存转储
	WHEN 10000071 THEN 'OIQR' --库存盘点过账
	WHEN 202 THEN 'OWOR' --生产订单
	END 
	INTO table1
	FROM DUMMY;
	
	--确定子表,然后插入到table2里
	SELECT
	CASE :object_type
	WHEN 15 THEN 'DLN1' --销售交货
	WHEN 16 THEN 'RDN1' --销售退货
	WHEN 13 THEN 'INV1' --应收发票
	WHEN 14 THEN 'RIN1' --应收贷项凭证
	WHEN 20 THEN 'PDN1' --采购收货
	WHEN 21 THEN 'RPD1' --采购退货
	WHEN 18 THEN 'PCH1' --应付发票
	WHEN 19 THEN 'RPC1' --应付贷项凭证
	WHEN 59 THEN 'IGN1' --收货
	WHEN 60 THEN 'IGE1' --发货
	WHEN 67 THEN 'OWTR' --库存转储
	WHEN 10000071 THEN 'IQR1' --库存盘点过账
	WHEN 202 THEN 'WOR1' --生产订单
	END
	INTO table2
	FROM DUMMY;

    -- 构建动态 SQL
    v_sql := 
	'SELECT COUNT(*) FROM
	(
	SELECT COUNT(A."U_ID") FROM
	(
	SELECT DISTINCT T1."DocEntry",T1."U_ID" 
	FROM "' || :table1 || '" T0
	INNER JOIN "' || :table2 || '" T1 ON T0."DocEntry" = T1."DocEntry"
	WHERE T0."CANCELED" = ''N''
	AND IFNULL(T1."U_ID",'''') IN (SELECT "U_ID" FROM "' || :table2 || '" WHERE "DocEntry" = ' || :list_of_cols_val_tab_del || ')) A GROUP BY A."U_ID" HAVING COUNT(*) > 1);'
	;
	
    -- 执行并传递绑定变量
    EXECUTE IMMEDIATE :v_sql INTO SAP_COUNT;

	IF IFNULL(SAP_COUNT,0) > 0
		THEN
			error := 1;
			error_message := N'【'|| :table1 ||'】,此ID已存在,不允许重复传入SAP,请核实!';
	END IF;
END IF;
-----------------------------------------------------------------------------------------

-- Select the return values
select :error, :error_message FROM dummy;

end;

注意事项:

  • v_sql里面的拼接字符串,一定要注意区分单引号,因为在拼接的时候,用到单引号的地方,需要用两个单引号进行表示。
  • 此方案一定要核实所有的业务单据,因为很容易发生各种各样的SQL报错,尤其是单引号、分号的问题,双引号后面不要跟回车。
  • 此方案仅提供思路,具体需要根据实际情况进行更改SQL代码控制。
  • 自行搜索一下EXECUTE IMMEDIATE的语法。
http://www.dtcms.com/a/113244.html

相关文章:

  • 智慧节能双突破 强力巨彩谷亚VK系列刷新LED屏使用体验
  • 初识Linux-基本常用指令(一篇学会操作指令)
  • 03.unity开发资源 获取
  • 05.unity 游戏开发-3D工程的创建及使用方式和区别
  • Windows程序中计时器WM_TIMER消息的使用
  • Golang的Goroutine(协程)与runtime
  • 使用MATIO库读取Matlab数据文件中的稀疏矩阵
  • JAVA阻塞队列
  • OrangePi入门教程(待更新)
  • C++开发工具全景指南
  • 【java】在 Java 中,获取一个类的`Class`对象有多种方式
  • 6.5.图的基本操作
  • YOLOX 检测头以及后处理
  • 联网汽车陷入网络安全危机
  • 贪心算法之任务选择问题
  • mmap函数的概念和使用方案
  • 爬楼梯问题-动态规划
  • 3536 矩形总面积
  • leetcode4.寻找两个正序数组中的中位数
  • 类 和 对象 的介绍
  • 2024 .11-2025.3 一些新感悟
  • 【33期获取股票数据API接口】如何用Python、Java等五种主流语言实例演示获取股票行情api接口之沪深A股当天逐笔交易数据及接口API说明文档
  • 【2020】【论文笔记】相变材料与超表面——
  • 使用Cusor 生成 Figma UI 设计稿
  • 数据库并发控制问题
  • 麒麟系统桌面版本v10安装教程
  • 【动手学深度学习】卷积神经网络(CNN)入门
  • 低代码开发平台:飞帆画 echarts 柱状图
  • pygame里live2d的使用方法(live2d-py)
  • 人工智能与计算机技术赋能高中教育数字化教学模式的构建与实践