甲骨文11g这似乎比应该做的难,所以我在这里可能走错了路。我有一个生成用户定义表单的应用程序,我的数据比这要复杂一些,但是想法是-我有一个数据表,其中包含来自用户定义表单的所有数据输入create table formData( id number , fName varchar(100) , lName varChar(100) , mName varChar(100) , formType varchar(100) ...);insert all into formData(id,fName,lName,mName,formType)values(1,'Bob','Smith',NULL,'birthday') into formData(id,fName,lName,mName,formType)values(2,'Jim','Jones','Wilber','birthday') into formData(id,fName,lName,mName,formType)values(3,'Frank','Peterson',NULL,'general') into formData(id,fName,lName,mName,formType)values(4,'Alex','Anderson',NULL,'general')我有一个表,其中包含动态表单的字段选项create table fieldOptions( id number , fieldName varchar(100) , fieldLabel varChar(100) , formType varchar(10) , fieldUsed number , ...);insert all into fieldOptions (fieldName,fieldLabel,formType,fieldUsed)values('fName','First Name','birthday',1) into fieldOptions (fieldName,fieldLabel,formType,fieldUsed)values('lName','Last Name','birthday',1) into fieldOptions (fieldName,fieldLabel,formType,fieldUsed)values('mName','Middle','birthday',1) into fieldOptions (fieldName,fieldLabel,formType,fieldUsed)values('fName','First','general',1) into fieldOptions (fieldName,fieldLabel,formType,fieldUsed)values('lName','Surname','general',1) into fieldOptions (fieldName,fieldLabel,formType,fieldUsed)values('mName','Middle Initial','general',0)我想在程序包中创建一个过程,该过程将使光标返回到包含以下数据的.net页面:其中ID = 3(常规输出) Label | Value--------+---------First | FrankSurname | Peterson或ID = 1(生日输出) Label | Value------------+---------First Name | BobLast Name | SmithMiddle | NULL我不确定是否可以在(枢轴?)查询中执行此操作。我开始玩弄通过处理数据构建的记录集合,但是如果这是解决方案,如何将记录集合放入out sys_refcursor?也许我已经考虑过了,可以通过几个子查询来完成?朝正确的方向推将是完美的,谢谢。 最佳答案 假设您的formData表结构是固定的并且是已知的,则只需使用一个case表达式将formOption.fName转换为匹配的列值即可:select fo.fieldLabel as label, case fo.fieldName when 'fName' then fd.fName when 'lName' then fd.lName when 'nName' then fd.mName end as valuefrom formData fdjoin fieldOptions foon fo.formType = fd.formtypewhere fd.id = 3;LABEL VALUE-------------------- --------------------First FrankSurname PetersonMiddle Initial...where fd.id = 3;LABEL VALUE-------------------- --------------------First Name BobLast Name SmithMiddle然后,您可以使用ID值的参数值,使过程打开该查询的ref游标。如果formData结构未知或不是静态的,那么您可能会遇到更大的问题。但是为此,您需要使用动态SQL。首先,您可以执行以下操作:create procedure p42 (p_id number, p_refcursor out sys_refcursor) as l_stmt varchar2(32767);begin l_stmt := 'select fo.fieldLabel as label, case lower(fo.fieldName) '; for r in ( select column_name from user_tab_columns where table_name = 'FORMDATA' and data_type = 'VARCHAR2' ) loop l_stmt := l_stmt || ' when ''' || lower(r.column_name) || ''' then fd.' || r.column_name; end loop; l_stmt := l_stmt || ' end as value ' || 'from formData fd ' || 'join fieldOptions fo ' || 'on fo.formType = fd.formtype ' || 'where fd.id = :d1'; open p_refcursor for l_stmt using p_id;end p42;/这将使用表中实际定义的所有列在运行时创建案例表达式。因为fieldName的大小写可能与数据字典不匹配,所以我将所有内容都强制小写以进行比较。我还限制字符串列以简化大小写,但是如果您需要其他数据类型的列,则case表达式的每个when ... then子句都需要检查该列的数据类型(可以将其添加到游标)并将相应的实际列值转换为字符串。所有值都必须以相同的数据类型结尾,因此实际上它必须是字符串。无论如何,可以从SQL * Plus进行测试:var rc refcursorexec p42(1, :rc);PL/SQL procedure successfully completed.print rcLABEL VALUE-------------------- --------------------First Name BobLast Name SmithMiddle3 rows selected.您可以查询r来获取可能的列名,但是您仍然可能会遇到数据类型转换的问题,这将很难处理。但是,如果所有引用的fieldOptions字段实际上都是字符串,则为: for r in ( select fo.fieldName from formData fd join fieldOptions fo on fo.formType = fd.formtype where fd.id = p_id ) loop l_stmt := l_stmt || ' when ''' || r.fieldName || ''' then fd.' || r.fieldName; end loop;
09-11 18:33