oracle - Oracle PL/SQL - 取消引用字符串作为变量
问题描述
是否可以取消引用字符串作为 PL/SQL 中的变量?
我正在寻找这样的东西:
declare
my_var CONSTANT varchar2(50) := 'test';
my_var_ref CONSTANT varchar2(50) := 'my_var';
begin
-- This of course doesn't work, it's just to illustrate what I'm looking for:
DBMS_OUTPUT.PUT_LINE(&my_var_ref) -- Prints test
end;
将名称作为过程参数传递:
declare
my_var CONSTANT varchar2(50) := 'test';
my_var_ref CONSTANT varchar2(50) := 'my_var';
begin
my_func(&my_var_ref) -- Pass my_var instead of my_var_ref
end;
解决方案
[TL;DR] 不,您不能取消引用 PL/SQL 变量。但是,另一种选择可能是使用关联数组。
如果您尝试使用取消引用它EXECUTE IMMEDIATE
,则动态评估的 PL/SQL 块不知道调用块的上下文,因此无法获取取消引用变量的值。
例如:
DECLARE
my_var CONSTANT varchar2(50) := 'test';
my_var_ref CONSTANT varchar2(50) := 'my_var';
value VARCHAR2(50);
plsql_block VARCHAR2(100) := 'BEGIN :value := ' || my_var_ref || '; END;';
BEGIN
DBMS_OUTPUT.PUT_LINE( plsql_block );
EXECUTE IMMEDIATE plsql_block USING IN OUT value;
DBMS_OUTPUT.PUT_LINE( value );
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE( SQLERRM );
END;
/
输出:
BEGIN :value := my_var; END; ORA-06550: line 1, column 17: PLS-00201: identifier 'MY_VAR' must be declared
它有正确的变量名,但该变量未在发生 PL/SQL 块的动态评估的上下文中定义,因此它不起作用。
但是,如果您尝试传入变量的值(而不是尝试取消引用变量),那么这表明,除了取消引用之外,其余代码都可以工作:
DECLARE
my_var CONSTANT varchar2(50) := 'test';
my_var_ref CONSTANT varchar2(50) := 'my_var';
value VARCHAR2(50);
plsql_block VARCHAR2(100) := 'BEGIN :value := ''' || my_var || '''; END;';
BEGIN
DBMS_OUTPUT.PUT_LINE( plsql_block );
EXECUTE IMMEDIATE plsql_block USING IN OUT value;
DBMS_OUTPUT.PUT_LINE( value );
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE( SQLERRM );
END;
/
输出:
BEGIN :value := 'test'; END; test
但是,您可以改用 PL/SQL 关联数组:
DECLARE
TYPE MAP IS TABLE OF VARCHAR2(50) INDEX BY VARCHAR2(50);
my_var_ref CONSTANT VARCHAR2(50) := 'my_var';
v_map MAP;
BEGIN
v_map('my_var') := 'test';
DBMS_OUTPUT.PUT_LINE( v_map( my_var_ref) );
END;
/
哪个输出:
test
db<>在这里摆弄
推荐阅读
- javascript - 在样式化组件中搜索反应道具时,我可以使用 .includes() 或 .contains() 或 .indexOf() 吗?
- java - DatabaseMetaData.getColumns 具有奇怪的 int 值列大小
- php - 在 Laravel 中这种路由方式是否正确?为相同的端点应用不同的路由
- java - 记录runnable的实例
- sql - 根据 Redshift 中其他表的条目在表中插入值
- sql - 在 Oracle 中使用 NOT LIKE
- python - 检查字符串列表并为每个特定字符串索引创建子列表
- javascript - 从对象数组中获取 3 个随机的、非重复的对象
- c# - 无法在面向 netcoreapp3.1 的 ASP.NET Core WebApp 中为特定 API 控制器启用 CORS
- asp.net - 实体框架类类型属性到蛇案例