当我们在 plsql 中动态传递列名的值和相应的列值时获取整行的存储过程

Posted

技术标签:

【中文标题】当我们在 plsql 中动态传递列名的值和相应的列值时获取整行的存储过程【英文标题】:Stored procedure to get the entire row when we dynamically pass the value for column name and the respective column value in plsql 【发布时间】:2017-07-16 12:55:50 【问题描述】:

我需要编写一个动态接受列名和列值并动态返回与列值匹配的整行的存储过程。

帮我写这个!!

谢谢

【问题讨论】:

什么没有特别好用? 【参考方案1】:

首先,我创建一个过程,该过程接受一列及其值

CREATE OR replace PROCEDURE Exec_query (column1 IN VARCHAR2,
                                                   value1  IN VARCHAR2,
                                                   row_out OUT hr.employees%ROWTYPE)
           IS
             query VARCHAR2(4000) := 'select * FROM EMPLOYEES WHERE '
                                     || column1
                                     || '='
                                     || value1;
             c1    SYS_REFCURSOR;
           BEGIN
               OPEN c1 FOR query;

               FETCH c1 INTO row_out;
           END;

           /

这里我获取employee_id = 100 的员工记录并显示first_name。使用连接运算符“||”写入您拥有的其他列内部 dbms_output.put_line()

           SET SERVEROUTPUT ON;
           DECLARE
               v_emp_row employees%ROWTYPE;
           BEGIN
               Exec_query('employee_id', '100', v_emp_row);

               dbms_output.Put_line(v_emp_row.first_name);
           END;

           /  

【讨论】:

我已经执行了这两个查询,但是为什么它没有将 first_name 显示为输出。??我还需要完整的行,不仅是 first_name.. 必须在开头使用 SET SERVEROUTPUT ON ;另外,您是否尝试过阅读和理解该程序?你不能花点力气把其他列写在 dbms_output.Put_line 里面吗? 在 PL/SQL 中,您无法像在 sqlplus 或其他 IDE 中观察到的那样直接显示选择查询的输出。您需要编写并显示列名。 这很危险!如果 value1 包含 "test' OR (1=1 AND ROWNUM=1) AND '0' = '1" 那么它将返回 wring 行。这可能会产生安全隐患。顺便说一句:我认为您在 value1 周围缺少单引号。【参考方案2】:

出于性能和安全原因,您应该使用绑定变量。

CREATE OR REPLACE FUNCTION GET_ROW_BY_EXAMPLE
      (column1 IN VARCHAR2,
          value1  IN VARCHAR2) 
 RETURN dual%ROWTYPE IS
      result dual%ROWTYPE;
BEGIN
    EXECUTE IMMEDIATE 
         'SELECT * FROM dual WHERE ' || column1 || ' = :value1'
         INTO result
         USING IN value1;
    return result;
END;

我建议你检查一下column1。在将表传递给字符串文字之前包含有效的列名。另请注意,如果 value1 不唯一并且查询返回两行,则没有错误处理。

将它放入一个包中并重载函数会非常好,这样你就有一个 value1 是 VARCHAR2,一个是 NUMBER,一个是 DATE 等等。然后你就不必担心字符串表示(例如小数分隔符和日期格式)。

【讨论】:

以上是关于当我们在 plsql 中动态传递列名的值和相应的列值时获取整行的存储过程的主要内容,如果未能解决你的问题,请参考以下文章

在 Oracle PLSQL 中使用游标的动态列名

SQL 动态列和更新多列

easyui中动态datagrid列名,根据不同的条件查询数据库显示不同的列。一般处理程序中用session来弄columns

plsql的odbc如何删除不需要的列

请求用@variable 替换列名

每当在 PLSQL 中插入新行时,更改前一行和当前行中的列的值