使用具有运行时值的过程从 table 执行数据验证规则
Executing data validation rules from a table using a procedure with runtime values
我有一个 table 充满了许多数据验证查询。例如一行:
SELECT end_time - start_time
FROM mt_process_status
WHERE process_id = <PROCESS_ID> AND ref_date = <REF_DATE>
我必须执行所有这些 SQL 语句,用 运行 时间值填充“<>”中的值,并检查进程的性能是否没有改变。
这可以用存储过程来完成吗?我想了解解决方案是什么样的。此类文档的任何链接,任何可以指导我正确方向的东西。
CREATE OR REPLACE PROCEDURE MY_PROC(g_id)
AS
l_query varchar2(1000);
l_duration number;
BEGIN
-- Get the query from the table
select query into l_query from my_table where id=g_id;
-- l_query contains "select end_time - start_time from mt_process_status where process_id = <PROCESS_ID> and ref_date = <REF_DATE>"
-- Put value to replace the tags (take care of code injection...)
l_query := REPLACE(l_query,'<PROCESS_ID>', something);
l_query := REPLACE(l_query,'<REF_DATE>', something_else);
EXECUTE IMMEDIATE lquery RETURN INTO l_duration;
-- Do what you have to do...
-- If you do a function, then you can:
-- RETURN l_duration;
END;
/
你的问题不清楚。这是你问题的答案。在过程中使用变量。
问候。
我会把参考数据放在另一个 table 中并作为一个连接
在某个地方,您的组织中有一群分析师互相告诉,"We've done the difficult stuff, we've defined the queries. All the database has to do is execute them, how hard can that be?"答案:非常难。
让我们来看看您发布的查询:
select end_time - start_time from mt_process_status where process_id = <PROCESS_ID> AND ref_date = <REF_DATE>
使用 replace(the_str, '<PROCESS_ID>', 1234)
替换值非常简单。但是对于 ref_date
来说,这大概是一个日期,所以它需要是 replace(the_str, '<REF_DATE>', 'date ''2017-01-01''')
。开始变得恶心,这只是处理文字。当替换值作为参数传递时,它会更加棘手。
当然,我假设 PROCESS_ID 是数字。也许不是。谁能告诉?是否有定义这些细节的数据字典?
如果使用动态 SQL 占位符定义查询会更容易:
select end_time - start_time from mt_process_status where process_id = :PROCESS_ID AND ref_date = :REF_DATE
那么你可以忘记替换,只需 运行
execute immediate the_str
using 1234, date '2017-01-01'
into whatever;
但是您仍然需要知道有多少个占位符、它们出现的顺序以及它们是什么数据类型。可能感觉这是软编码和可配置的,但在查询和调用它的程序之间仍然存在真正的硬依赖。
此外,您还失去了进行影响分析的能力。当您更改 mt_process_status
时,哪些查询会受到影响?谁能告诉?
我有一个 table 充满了许多数据验证查询。例如一行:
SELECT end_time - start_time
FROM mt_process_status
WHERE process_id = <PROCESS_ID> AND ref_date = <REF_DATE>
我必须执行所有这些 SQL 语句,用 运行 时间值填充“<>”中的值,并检查进程的性能是否没有改变。
这可以用存储过程来完成吗?我想了解解决方案是什么样的。此类文档的任何链接,任何可以指导我正确方向的东西。
CREATE OR REPLACE PROCEDURE MY_PROC(g_id)
AS
l_query varchar2(1000);
l_duration number;
BEGIN
-- Get the query from the table
select query into l_query from my_table where id=g_id;
-- l_query contains "select end_time - start_time from mt_process_status where process_id = <PROCESS_ID> and ref_date = <REF_DATE>"
-- Put value to replace the tags (take care of code injection...)
l_query := REPLACE(l_query,'<PROCESS_ID>', something);
l_query := REPLACE(l_query,'<REF_DATE>', something_else);
EXECUTE IMMEDIATE lquery RETURN INTO l_duration;
-- Do what you have to do...
-- If you do a function, then you can:
-- RETURN l_duration;
END;
/
你的问题不清楚。这是你问题的答案。在过程中使用变量。
问候。
我会把参考数据放在另一个 table 中并作为一个连接
在某个地方,您的组织中有一群分析师互相告诉,"We've done the difficult stuff, we've defined the queries. All the database has to do is execute them, how hard can that be?"答案:非常难。
让我们来看看您发布的查询:
select end_time - start_time from mt_process_status where process_id = <PROCESS_ID> AND ref_date = <REF_DATE>
使用 replace(the_str, '<PROCESS_ID>', 1234)
替换值非常简单。但是对于 ref_date
来说,这大概是一个日期,所以它需要是 replace(the_str, '<REF_DATE>', 'date ''2017-01-01''')
。开始变得恶心,这只是处理文字。当替换值作为参数传递时,它会更加棘手。
当然,我假设 PROCESS_ID 是数字。也许不是。谁能告诉?是否有定义这些细节的数据字典?
如果使用动态 SQL 占位符定义查询会更容易:
select end_time - start_time from mt_process_status where process_id = :PROCESS_ID AND ref_date = :REF_DATE
那么你可以忘记替换,只需 运行
execute immediate the_str
using 1234, date '2017-01-01'
into whatever;
但是您仍然需要知道有多少个占位符、它们出现的顺序以及它们是什么数据类型。可能感觉这是软编码和可配置的,但在查询和调用它的程序之间仍然存在真正的硬依赖。
此外,您还失去了进行影响分析的能力。当您更改 mt_process_status
时,哪些查询会受到影响?谁能告诉?