【问题标题】:Stored Procedure to return specific rows plsql返回特定行的存储过程plsql
【发布时间】:2017-12-16 11:28:42
【问题描述】:

假设我有一张桌子:

 create table product
(
  prod_code number(3),
  prod_name varchar2(20),
  prod_dept varchar2(20)
);

我想写一个接收两个参数的过程:

param_1 = col_name
param_2 = col_value

该过程需要检查该列是否存在,如果存在则返回值等于param_2 的行。

例子:

假设过程名称为getproddetails,传递的参数是这样的:

执行getproddetails('prod_id', 40)

当我传递这两个值时,它应该返回带有prod_id=40 的整行。

我可以检查该列是否存在,但如何根据值返回整行?

任何帮助都会很棒。我已经编写了以下代码,但它不起作用:

create or replace procedure getproductdetails(p_colname varchar2, p_value number)
is
  v_column_exists number :=0;
  cursor c1 is select * from product where p_colname = p_value;
  myrow c1%rowtype;
    BEGIN
    select count(*) into v_column_exists
    from user_tab_cols
    where column_name = p_colname and table_name = 'PRODUCT';

   if(v_column_exists > 0) then
     open c1;
      loop
        fetch c1 into myrow;
        exit when c1%notfound;
        dbms_output.put_line(myrow.prod_name || ' ' || myrow.prod_cost);
      end loop;
    else
      dbms_output.put_line('Column Not Found');
    end if;
   end getproductdetails;

请注意,我只显示 2 列,但大约有 8 到 9 列。

【问题讨论】:

  • 为什么需要这样做?是为了作业还是什么?对于现实世界的应用程序来说,这似乎是一个奇怪的要求(虽然奇怪!= 不可能!)
  • 不完全是硬件,只是想学习。如何使用可以是数字或 varchar 的值。如果不能同时使用这两种数据类型,那么至少如何使用数字数据类型来完成,因为 param_2 是一个数字。
  • 一般来说,尝试有一个通用代码的过程是个坏主意 - 它使事情变得复杂,因为现在您必须处理数据转换(如果值是数字或日期?)如您所见。相反,最好知道您的应用程序想要什么并针对具体情况编写代码 - 例如。有一个返回给定 emp_id 的整行的过程,并有一个在传入 emp_name 时返回行的过程,等等。你所追求的是可行的,但你必须问问自己这是否真的有意义这样做。
  • 请参阅this article,了解为什么泛化不一定是好事,尤其是在极端情况下!
  • 我确实理解为什么这是一个坏主意,但只是知道它是否可以完成。真正的要求是传递列名和将确定 varchar 或数字的值。那么,我怎样才能用一个数字呢?与上述问题中的示例 1 一样

标签: oracle stored-procedures plsql oracle11g


【解决方案1】:

如何根据值返回整行?

你可以创建一个out参数,它可以是表的类型,比如:

Procedure gettemplates( columnname in varchar2, value in varchar2, entirerowreturn out yourtable%rowtype) is ...

【讨论】:

  • 如果要返回多行,那将无济于事。相反,我会使用参考光标。
【解决方案2】:

如果将param_2设置为VARCHAR2就可以了;使用隐式转换。

这是我要做的,使用REF_CURSOR:

create or replace procedure getempdetails (
   pcol_name in varchar2
 , pcol_value in varchar2
 , pres_cursor out sys_refcursor
) is 
begin
  open pres_cursor for 'SELECT emp_id, emp_name, emp_dept FROM emp WHERE '
  ||pcol_name||'='''||pcol_value||'''';
end;
/

编辑:使用:pcol_name 更优雅;

但我找不到如何使其与隐式转换一起使用。

create or replace procedure getempdetails (
   pcol_name in varchar2
 , pcol_value in varchar2
 , pres_cursor out sys_refcursor
) is 
begin
   OPEN pres_cursor 
    FOR 'SELECT emp_id, emp_name, emp_dept FROM emp WHERE :pcol_name='''||pcol_value||''''
  USING pcol_name;
end;

/

然后这样使用光标:

SQL>  insert into emp values(1, 'John', 'IT');

1 row created.

SQL> variable r refcursor;
SQL> exec  getempdetails('emp_id', '1', :r);

PL/SQL procedure successfully completed.

SQL>  print r
         1 John                 IT

SQL>

如果您想在进一步的 PL/SQL 中使用此游标,请多搜索一点。例如。 here 或 here 等很好的例子。

注意: 基本上,in PL/SQL, ' escapes '。因此,如果您想在 PL/SQL 中的字符串中包含 ',请编写 ' I want a quote there -> '' <- '

【讨论】:

  • 您正在使用 3 个参数调用该过程。请检查我在以前的 cmets 中发布的代码。
  • @KaranGupta,您必须编辑您的问题以避免此类误解。我会等待进一步通知。
  • 您的代码运行良好,但请告诉我有关“||”的信息使用的运算符。无论如何感谢您的回答。
  • 谢谢,|| 是串联操作。
  • 是的,我知道它是连接,但我不明白它是如何以及为什么在这里使用的?单引号使它更加混乱。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-01
  • 2018-08-13
  • 2014-08-31
  • 1970-01-01
  • 2012-07-19
相关资源
最近更新 更多