创建 Oracle 函数 - 如何减少样板代码

Posted

技术标签:

【中文标题】创建 Oracle 函数 - 如何减少样板代码【英文标题】:Create Oracle functions - how to reduce boilerplate code 【发布时间】:2019-04-02 16:22:03 【问题描述】:

我有两个查询语句,它们完全相同,只有 3 列不同,我用于创建数据透视表。前两列给出了枢轴的维度,而第三列包含我们称之为聚合函数的数据。

我是 SQL 新手,所以我想知道是否有任何干净的方法来定义一个具有 3 个列名参数和第 4 个参数的函数,它给出了聚合函数。

SELECT *
FROM (
  SELECT SDDCTO, SDSRP4, SDSOQS
  FROM MyTable
)
PIVOT (
  sum(SDSOQS)  
  for SDDCTO 
  IN ('EB' AS EB 
      'EL' AS EL, 
      'ER' AS ER, 
      'ES' AS ES, 
      'E1' AS E1, 
      'E2' AS E2, 
      'E5' AS E5 
      'E9' AS E9
      )
)
ORDER BY SDSRP4
;

-- Same query with different columns and aggregate function
SELECT *
FROM (
  SELECT SDDCTO, SDMCU, SDAEXP
  FROM MyTable
)
PIVOT (
  avg(SDAEXP)  
  for SDDCTO 
  IN ('EB' AS EB, 
      'EL' AS EL, 
      'ER' AS ER, 
      'ES' AS ES, 
      'E1' AS E1, 
      'E2' AS E2, 
      'E5' AS E5, 
      'E9' AS E9
      )
)
ORDER BY SDMCU
;

【问题讨论】:

【参考方案1】:

对于较早的实际项目,您对动态 SQL 和 from 子句中的函数感到满意 - 从长远来看会更好。

我讨厌两次编写相同或相似的代码。所以最好的选择是这样的

select ...
from table(plsql_package ( parameters ))

【讨论】:

您认为开始学习动态 SQL 的最佳角度、文档或教程是什么?老实说,乍一看似乎有点硬核。 时代变了——现在执行即时界面变得非常简单。因此,只需查找立即执行的文档并从那里构建。然后查看它的游标。你有一个很好的项目要构建,它更容易学习。【参考方案2】:

这不使用函数,它必须使用动态 SQL 可能比两个单独的查询更难维护;但是您可以创建一个将两个聚合组合在一起的视图:

CREATE VIEW MyView AS
SELECT *
FROM (
  SELECT SDDCTO, SDSRP4, SDSOQS, SDMCU, SDAEXP
  FROM MyTable
)
PIVOT (
  sum(SDSOQS) as SUM_SDOQS,
  avg(SDAEXP) as AVG_SDAEXP
  for SDDCTO 
  IN ('EB' AS EB, 
      'EL' AS EL, 
      'ER' AS ER, 
      'ES' AS ES, 
      'E1' AS E1, 
      'E2' AS E2, 
      'E5' AS E5, 
      'E9' AS E9
      )
)
;

...然后在您的两个查询中查询视图,而不是表:

SELECT SDSRP4, EB_SUM_SDOQS, EL_SUM_SDOQS, ER_SUM_SDOQS, ES_SUM_SDOQS,
  E1_SUM_SDOQS, E2_SUM_SDOQS, E5_SUM_SDOQS, E9_SUM_SDOQS
FROM MyView
ORDER BY SDSRP4
;

SELECT SDMCU, EB_AVG_SDAEXP, EL_AVG_SDAEXP, ER_AVG_SDAEXP, ES_AVG_SDAEXP,
  E1_AVG_SDAEXP, E2_AVG_SDAEXP, E5_AVG_SDAEXP, E9_AVG_SDAEXP
FROM MyView
ORDER BY SDMCU
;

虽然我不确定它会给你带来多少好处......

【讨论】:

好吧,为了让问题更简单,我撒了一点谎。老实说,我现在已经是第 11 次使用此代码了,因为我有很多列可以用来做数据透视。 您可以向视图中的枢轴添加更多聚合,向内部查询添加更多列;只要它们都需要相同的枢轴“in”和“for”子句。我认为要么就是这样,要么是使用动态 SQL 的(可能是流水线的)函数;但当然,其他人可能会想出一些我没想到的东西。

以上是关于创建 Oracle 函数 - 如何减少样板代码的主要内容,如果未能解决你的问题,请参考以下文章

如何在scala中使用单片机减少样板

如何减少 responseJSON 中的样板,就像我使用 URLRequestConvertible 对相关的 Web 调用进行分组一样

打字稿:如何在全局范围内进行一些导入?

减少 redux-thunk 样板

csharp 可绑定类减少mvvm中的样板代码(实现INotifyPropertyChanged)

Oracle中In函数的使用