返回Table vs Repeated Query

时间:2016-06-15 03:44:44

标签: sql oracle function

我让我们说3个程序使用基本相同的基本查询。有了这个,如果我有查询的更新,我必须同时复制到其他2个程序,以确保它被同步:

即:

PROCEDURE get_something(name IN VARCHAR2, result OUT VARCHAR2){

  SELECT * 
    FROM (SELECT * from multisource)
   WHERE col1 = name;

...

}

PROCEDURE get_something2(address IN VARCHAR2, result OUT VARCHAR2){

  SELECT * 
    FROM (SELECT * from multisource)
   WHERE col2 = address;

...

}

PROCEDURE get_something3(var IN VARCHAR2, result OUT VARCHAR2){

  SELECT * 
    FROM (SELECT * from multisource)
   WHERE col3 = var;

...

}

我正在考虑创建一个返回基本查询表的函数,并从3个过程中调用它。因此,如果我有更新,我将只更新函数下的查询。

即:

FUNCTION get_base()
        RETURN table_t
        PIPELINED IS

        rec            record_r;

    BEGIN

        SELECT * from multisource...

       (maybe a pipeleined funcion or cursor here)

        RETURN;
   END get_base;

然后

PROCEDURE get_something(name IN VARCHAR2, result OUT VARCHAR2){

      SELECT * 
        FROM (SELECT * from table(get_base))
       WHERE col1 = name;

    ...

    }

PROCEDURE get_something2(address IN VARCHAR2, result OUT VARCHAR2){

      SELECT * 
        FROM (SELECT * from table(get_base))
       WHERE col2 = address;

    ...

    }

PROCEDURE get_something3(var IN VARCHAR2, result OUT VARCHAR2){

  SELECT * 
    FROM (SELECT * from table(get_base))
   WHERE col3 = var;

...

}

我的问题是,这是一个好习惯吗?我是否会遇到性能问题?有替代解决方案吗?

3 个答案:

答案 0 :(得分:1)

为什么不调整你的逻辑和程序只使用一个这样的选择:

NULL

然后你调用你的程序只传递你想要处理的值,并在其他参数中传递Sub NextInvoice() Range("D3").Value = Range("D3").Value + 1 Range("B18:H43").ClearContents End Sub Sub SaveInvoiceNewName() Dim NewFN As Variant 'Copy invoice to a new workbook ActiveSheet.Copy NewFN = "C:\This PC\Documents\Brewing\Invoices\Invoice " & Range("C5").Value & Range("D3").Value & ".xlsm" ActiveWorkbook.SaveAs NewFN, FileFormat:=xlOpenXLSMWorkbookMacroEnabled ActiveWorkbook.Close NextInvoice End Sub

答案 1 :(得分:1)

表函数通常不是促进DRY(不要重复自己)原则的好方法。视图可能是更好的方法。

表功能齐全,解决了一些有趣的挑战。但它们有点过度使用,可能会导致一些问题:

  1. 它们会阻止优化程序转换。 Oracle在SQL优化方面非常出色,可以通过多种方式重写大量SQL语句。表函数使大多数这些技巧变得不可能。谓词推送和查看合并不会在表功能障碍中发生。在纯SQL方法中,并行性等功能是微不足道的,但使用表函数变得很困难。
  2. 它们并不常见。这不是避免某些事情的有力理由。但是,不要因为它的不同而使用某些东西。对你来说很酷的是对大多数人来说有点令人沮丧。更简单的方法通常是最好的。
  3. 他们有更多的错误。在我的经验表中,函数比常规SQL更复杂。这可能是因为它们不常见,并且没有经过测试和维护以及其他功能。你可以期待更多的ORA-600错误和更多的表函数陷阱。
  4. 视图是防止重复SQL的标准方法。

    不幸的是,大多数视图实现很糟糕。但是有一些简单的原因可以让观点变得如此丑陋。如果您提前计划,可以避免这些常见问题:

    1. 开发人员认为SQL不是一种真正的编程语言,并且不必遵循简单的代码指南。他们不愿意使用好的,可读的名字,他们不会使用评论,他们也不会花时间让代码看起来很好。
    2. 视图是一些神圣数据字典的一部分。只有DBA或者#34;架构师"被允许改变它们。这个过程涉及一些Rube Goldberg机器,它生成一个花哨的PDF文件,需要多个签名。该文件打印出来并贴在墙上,但没有人用它来进行有意义的工作。文书工作的所有开销意味着没有人会重构这些观点。

答案 2 :(得分:0)

表函数很棒!一个潜在的性能问题是优化器无法推高col1,col2或col3上的过滤器。

另一个替代方法是让你的表函数接受所有3个参数并仅应用非空参数。

有几种方法可以定义这个TFN查询:

  1. 使用OR过滤器。 不要这样做。它不太可能表现良好。

  2. 定义3个不同的查询并有条件地执行:IF p_X不为空...

  3. 使用UNION ALL连接3个查询并过滤 colX =:p_X和:p_X不为空 只会执行3个中的一个。

  4. 动态SQL。 如果经常执行这些查询,您将支付不使用绑定变量的惩罚。 光标共享可能没问题