Oracle 是否支持动态SQL
在执行更新时,我们希望对ORA_ROWSCN(Oracle db BTW)进行并发性检查。所以我在考虑创建一个函数,在这个函数中,你传入你拥有的ora_rowscn、表名、列名和一个ID。这个函数将根据你传入的表、列和ID执行一个select语句,如果返回的ora_rowscn与你传入的不同,则返回一个true或false 我对传入的表名和列名进行有效性检查,以确保它们首先存在Oracle 是否支持动态SQL,oracle,plsql,Oracle,Plsql,在执行更新时,我们希望对ORA_ROWSCN(Oracle db BTW)进行并发性检查。所以我在考虑创建一个函数,在这个函数中,你传入你拥有的ora_rowscn、表名、列名和一个ID。这个函数将根据你传入的表、列和ID执行一个select语句,如果返回的ora_rowscn与你传入的不同,则返回一个true或false 我对传入的表名和列名进行有效性检查,以确保它们首先存在 FUNCTION ConcurrencyCheck ( pi_orarowscn_in I
FUNCTION ConcurrencyCheck (
pi_orarowscn_in IN NUMBER,
pi_table_name IN VARCHAR2,
pi_column_name IN VARCHAR2,
pi_id IN NUMBER
)
RETURN BOOLEAN IS
r_data_out_of_date BOOLEAN := false;
ln_orarowscn_current NUMBER := 0;
lv_sql VARCHAR2(300) := '';
lv_column VARCHAR(20) := '';
lv_table VARCHAR(20) := '';
BEGIN
SELECT table_name INTO lv_table from ALL_TABLES WHERE TABLE_NAME = pi_table_name;
IF lv_table = '' THEN
RAISE NO_DATA_FOUND;
ELSE
SELECT column_name INTO lv_column from USER_TAB_COLUMNS WHERE TABLE_NAME = pi_table_name AND COLUMN_NAME = pi_column_name;
IF lv_column = '' THEN
RAISE NO_DATA_FOUND;
ELSE
lv_sql := 'select ORA_ROWSCN from ' || pi_table_name || ' where ' || pi_column_name || ' = ' || pi_id || '';
EXECUTE IMMEDIATE lv_sql INTO ln_orarowscn_current;
IF ln_orarowscn_current <> pi_orarowscn_in THEN
r_data_out_of_date := true;
END IF;
END IF;
END IF;
RETURN r_data_out_of_date;
EXCEPTION
WHEN NO_DATA_FOUND THEN
RAISE;
WHEN OTHERS THEN
RAISE;
END ConcurrencyCheck;
但是我一直收到一个SQL错误,说表是错误的
另一种解决方案是为所有表创建一个子函数,该子函数将为每个表返回ORA_ROWSCN,并在主函数中创建一个IF ELSE来调用每个表
我在这里寻找最佳实践。现在是否可以接受动态SQL?还是我应该走“长”路线,为每个表创建大量函数/过程
谢谢大家! 对于最佳实践,在这些情况下,建议使用
sys.dbms\u assert
包
FUNCTION ConcurrencyCheck(
pi_orarowscn_in IN NUMBER,
pi_table_name IN VARCHAR2,
pi_column_name IN VARCHAR2,
pi_id IN NUMBER
)
RETURN BOOLEAN IS
ln_orarowscn_current NUMBER := 0;
lv_sql VARCHAR2(300) := '';
BEGIN
lv_sql := '
select X.ora_rowscn
from '||sys.dbms_assert.sql_object_name(pi_table_name)||' X
where X.'||sys.dbms_assert.simple_sql_name(pi_column_name)||' = :pi_id
';
execute immediate lv_sql
into ln_orarowscn_current
using in pi_id;
return ln_orarowscn_current <> pi_orarowscn_in;
END ConcurrencyCheck;
函数并发检查(
pi_或Rowscn_的数量,
VARCHAR2中的pi_表_名称,
VARCHAR2中的pi_列_名称,
以数字表示的pi_id
)
返回布尔值为
ln_或Rowscn_当前编号:=0;
lv_sql VARCHAR2(300):='';
开始
lv_sql:='
选择X.ora_rowscn
从“| | sys.dbms_assert.sql_object_name(pi_table_name)| |”X
其中X.。|| sys.dbms_assert.simple_sql_name(pi_column_name)||'=:pi_id
';
执行立即lv_sql
进入ln_或Rowscn_电流
在pi_id中使用;
返回ln_或rowscn_当前pi_或rowscn_in;
结束并发检查;
注意:如果我处在你的位置,我会给自己一个艰难的开始,为每个表一次检查的函数包实现一个元数据驱动的代码生成器,正如你可能猜到的那样,这将是静态PL/SQL代码–为你提供所有漂亮的编译时语法/语义检查。至于最佳实践,在这些情况下,建议使用
sys.dbms\u assert
包
FUNCTION ConcurrencyCheck(
pi_orarowscn_in IN NUMBER,
pi_table_name IN VARCHAR2,
pi_column_name IN VARCHAR2,
pi_id IN NUMBER
)
RETURN BOOLEAN IS
ln_orarowscn_current NUMBER := 0;
lv_sql VARCHAR2(300) := '';
BEGIN
lv_sql := '
select X.ora_rowscn
from '||sys.dbms_assert.sql_object_name(pi_table_name)||' X
where X.'||sys.dbms_assert.simple_sql_name(pi_column_name)||' = :pi_id
';
execute immediate lv_sql
into ln_orarowscn_current
using in pi_id;
return ln_orarowscn_current <> pi_orarowscn_in;
END ConcurrencyCheck;
函数并发检查(
pi_或Rowscn_的数量,
VARCHAR2中的pi_表_名称,
VARCHAR2中的pi_列_名称,
以数字表示的pi_id
)
返回布尔值为
ln_或Rowscn_当前编号:=0;
lv_sql VARCHAR2(300):='';
开始
lv_sql:='
选择X.ora_rowscn
从“| | sys.dbms_assert.sql_object_name(pi_table_name)| |”X
其中X.。|| sys.dbms_assert.simple_sql_name(pi_column_name)||'=:pi_id
';
执行立即lv_sql
进入ln_或Rowscn_电流
在pi_id中使用;
返回ln_或rowscn_当前pi_或rowscn_in;
结束并发检查;
注意:如果我处在你的位置,我会给自己一个艰难的开始,为每个表一次检查的函数包实现一个元数据驱动的代码生成器,正如你可能猜到的,静态PL/SQL代码–为您提供了所有漂亮的编译时语法/语义检查。不幸的是,绑定变量不能用于表名或列名,只能用于数据,您别无选择,必须使用动态SQL谢谢回复。这就是我想的。您认为使用动态SQL还是使用一组主函数将调用的过程更好?我不会创建过程,因为您的代码将更难阅读和理解。但我认为还有改进的方法。例如,为什么不立即检查表名和列名的存在性?函数思想也不错,可能返回游标或varray?Cyrille:当然,这应该只是一次检查。谢谢你的意见。Ted:这个函数实际上返回一个布尔值,并且工作正常。我只是想知道安全实现和最佳实践。谢谢不幸的是,bind变量不能用于表名或列名,只能用于数据,您别无选择,必须使用动态sqls。谢谢回复。这就是我想的。您认为使用动态SQL还是使用一组主函数将调用的过程更好?我不会创建过程,因为您的代码将更难阅读和理解。但我认为还有改进的方法。例如,为什么不立即检查表名和列名的存在性?函数思想也不错,可能返回游标或varray?Cyrille:当然,这应该只是一次检查。谢谢你的意见。Ted:这个函数实际上返回一个布尔值,并且工作正常。我只是想知道安全实现和最佳实践。谢谢