【问题标题】:Oracle Stored Procedure If Not Exists ReturnOracle 存储过程如果不存在则返回
【发布时间】:2015-06-16 07:09:49
【问题描述】:

我一直是一个严格的 MS SQL 消费者,但我的任务是编写一个 Oracle 存储过程来比较 2 个表的缺失数据。如果订单丢失,我需要写一些返回 1 的东西。到目前为止,我有以下内容,但它甚至还没有接近工作。我在网上搜索了一点结果。任何帮助将不胜感激。

CREATE OR REPLACE PROCEDURE SP_PO_CHECK


AS

BEGIN

IF NOT EXISTS ( SELECT PO FROM ORDERS, PO_LIST, WHERE Order_PO = PO; ) THEN RETURN 0; ELSE RETURN 1

END;

【问题讨论】:

  • 您要执行的确切测试是什么?要返回 1,ORDERS 中是否必须至少存在一条记录,而 PO_LIST 表中没有对应的 PO 值,我们是这样吗?
  • 我正在尝试确定 PO_LIST 表中是否有不在 ORDERS 表中的 PO。如果 ORDERS 中不存在 PO_LIST.PO,则返回 0,否则返回 1。

标签: oracle if-statement procedure not-exists


【解决方案1】:

识别这种情况的正确查询是:

select count(*)
from   po_list p
where  not exists (
         select 1
         from   orders o
         where  o.order_po = p.po)
  and  rownum = 1;

这将在发现问题 po 后立即停止查询,并返回 0 或 1。

所以选择它到一个变量中并返回 1 - 它的值:

create or replace function missing_order
as
  missing_po_found integer;
begin
  select count(*)
  into   missing_po_found
  from   po_list p
  where  not exists (
           select 1
           from   orders o
           where  o.order_po = p.po)
  and    round = 1;

  return 1 - missing_o_found;
end;

没有运行,所以不能 100% 确定没有错字。

【讨论】:

  • 感谢@David Aldridge
【解决方案2】:

试试这样的:

RETURN CASE WHEN (SELECT COUNT(*) FROM ORDERS, PO_LIST, WHERE Order_PO = PO; ) <> (SELECT COUNT(*) FROM ORDERS) THEN 0 ELSE 1 END

【讨论】:

    【解决方案3】:

    首先它需要是函数而不是过程。

    然后您需要定义如何检查两个表中的存在性。您可以使用主表左连接到详细表并检查它是否为某些强制列返回 NOT NULL(我使用 rowid 因为它始终不为空)。 或者你可以使用 NOT EXISTS 子句。

    然后您需要使用 INTO 子句将结果返回到 PL_SQL 变量中 最后返回变量作为函数的结果。

    CREATE OR REPLACE FUNCTION SP_PO_CHECK
    RETURN NUMBER
    AS
     l_total_cnt number; 
     l_match_cnt number;
    BEGIN
      select count(*), -- total count of record only in po_list. I assume that this is your drive table. If not you can switch tables or use full outer join
             count(orders.rowid) -- count of records exist in both tables
        into l_total_cnt, l_match_cnt
        from po_list
        left join orders
          on Order_PO = PO;
    
      if l_total_cnt =  l_match_cnt then 
        return 1;
      else 
        return 0; 
      end if;
    
    END SP_PO_CHECK;
    

    【讨论】:

      【解决方案4】:

      你可以使用MINUS:

      CREATE PROCEDURE SP_PO_CHECK (
        hasSamePOs  OUT NUMBER
      )
      AS
        p_rowcount
      BEGIN
        SELECT COUNT(1)
        INTO   p_rowcount
        FROM   (
                 SELECT PO FROM PO_LIST
                 MINUS
                 SELECT PO FROM ORDERS
               );
        hasSamePOs := CASE WHEN p_rowcount > 0 THEN 0 ELSE 1 END;
      END;
      /
      

      或者

      CREATE PROCEDURE SP_PO_CHECK (
        hasSamePOs   OUT NUMBER
      )
      AS
      BEGIN
        SELECT CASE WHEN EXISTS (
                      SELECT PO FROM PO_LIST
                      MINUS
                      SELECT PO FROM ORDERS
                    )
                    THEN 0
                    ELSE 1
                    END
        INTO   hasSamePOs
        FROM   DUAL;
      END;
      /
      

      【讨论】:

        猜你喜欢
        • 2023-04-06
        • 1970-01-01
        • 2019-09-06
        • 1970-01-01
        • 2012-07-11
        • 2021-03-22
        • 2014-05-28
        • 2011-01-31
        相关资源
        最近更新 更多