【发布时间】:2017-12-11 04:57:56
【问题描述】:
我是 PL SQL 的新手,还在学习,但我需要解决一个问题,我对 PL SQL 的了解还不够,无法快速解决我的问题。
我引用了两个表:用户和属性。我有一个需要 3 个参数的过程:attrib_id、uid、attrib_value。
我首先用 attrib_id 查询了 attributes 表以返回属性名称并将其分配给变量。我的代码到此为止。
接下来我想在另一个select语句中使用前一个select语句创建的变量来查询users表,并返回与该变量所代表的属性关联的当前值。
代码:
PROCEDURE value_update_proc_z(attrib_id INTEGER, uid IN VARCHAR2, attrib_value IN VARCHAR2)
IS
v_old_attrib_name attributes.attribute_name%TYPE;
v_oldattrib_value varchar2(100);
v_mymsg varchar2(2000);
BEGIN
EXECUTE IMMEDIATE 'SELECT attrib_name FROM attributes WHERE indx = ''' || attrib_id || '''' INTO v_old_attrib_name;
EXECUTE IMMEDIATE 'SELECT' || v_old_attrib_name || 'FROM USERS WHERE USERID = ''' || uid || '''' INTO v_oldattrib_value;
v_mymsg := v_old_attrib_name || ' ' || v_oldattrib_value;
END value_update_proc_z;
第一个查询应该根据传递给过程的数字从属性表中返回一个值。例如,如果 attrib_id = 1,则查询将返回 first_name,如果 attrib_id = 2,则返回 last_name,如果 attrib_id = 3,将被退回的电子邮件。返回的值将分配给变量 v_old_attrib_name。
在我的 select 语句中使用变量 v_old_attrib_name,我希望第二个查询会返回一个值,例如; last_name 会返回 williams,或者 email 会返回 bob@somewhere.com。此查询的结果将分配给变量 v_oldattrib_value。
目前,第一个 Execute Immediate 有效,当我显示消息时,我可以看到该变量的值,但是当我添加第二个 Execute Immediate 时,我收到一条消息,指出操作无法完成。这不是系统产生的错误,是以前的开发者设置的消息。
我愿意接受改进建议。
谢谢!
【问题讨论】:
-
我会质疑你为什么需要这个程序。在调用过程中使用这样的静态 SQL 会更简单:
select columnname from users where userid = :userid -
我需要先获取列名,以便在第二个 select 语句中使用它。正在向该过程传递一个属性 ID 号,该 ID 号引用属性表中的属性名称。因此,如果该过程的属性 id 为 1,则该属性的名称为 first_name,即 users 表中的列名。所以,在调用过程之前我不知道。
-
看看调用代码。那就是设置属性“id”的地方。那是您可以更改它的地方,因此您无需在每次有人想要查询记录时都查找数据字典。您在这里所拥有的具有“EAV”模式的许多缺点(被认为是反模式)。