PLSQL - 提高代码效率

时间:2015-09-25 17:12:13

标签: sql oracle select plsql plsqldeveloper

这个问题与PLSQL有关 - 用于提高代码和编码标准的效率。

非常感谢任何帮助,指示,参考或建议。

问题:

我有一个带有INPUT参数i_flag的plsql过程,其类型为BOOLEAN

基于此i_flag的值(可以是true或false),我必须执行sql查询。如果值为TRUE则SQL1(假设查询1.1),否则如果值为FALSE则将执行SQL2(假设查询1.2)。

除了添加where子句外,SQL2与SQL1相同。

SQL1(1.1)

select a.user_id, a.user_name, a.dept_id, b.country from user a , contact b
where a.user_id = b.user_id;

SQL1(1.2)

select a.user_id, a.user_name, a.dept_id, b.country from user a , contact b
where a.user_id = b.user_id
and a.user_status is not null;

而不是在plsql中编写IF-ELSE,是否可以在单个SQL查询中编写此查询?

5 个答案:

答案 0 :(得分:3)

您可以使用逻辑or运算符在单个查询中创建相同的行为:

select a.user_id, a.user_name, a.dept_id, b.country 
from user a , contact b
where a.user_id = b.user_id AND (i_flag = TRUE OR a.user_status IS NOT NULL)

顺便说一下,隐式连接(在from子句中有两个表)是一种不推荐使用的语法,建议切换到现代的显式语法:

SELECT a.user_id, a.user_name, a.dept_id, b.country 
FROM   user a
JOIN   contact b ON a.user_id = b.user_id
where  i_flag = TRUE OR a.user_status IS NOT NULL

答案 1 :(得分:0)

首先,如果要在SQL查询中使用布尔参数,则必须替换类似sql的类型,例如NUMBER,即使用0或1而不是FALSE或TRUE。

其次,虽然Mureinik基于OR的答案将起作用,但如果您使用替代方案,Oracle通常会提供更好的性能。一种选择是这样的:

SELECT a.user_id, a.user_name, a.dept_id, b.country 
FROM   user a
JOIN   contact b ON a.user_id = b.user_id
WHERE  1 = CASE WHEN i_flag = 1 THEN 1
                WHEN a.user_status IS NOT NULL THEN 1
                ELSE 0 END

它并不漂亮,但在较大的查询中,它有时会有很大帮助。

答案 2 :(得分:0)

语法方面,所有上述答案都很棒。 然而,我的两分钱指的是可能有助于你表现的不同改动。当PL / SQL和SQL引擎(由ORACLE的架构分离)之间的弹跳时,可以看到运行PL / SQL过程时最大的瓶颈。因此,经验法则是尽量减少每个程序的单个调用量。

如果我们将此规则应用于您的问题 - 您应该检查是否可以将refcursor传递给包含要查询的所有用户的过程及其相应的布尔值。如果现在从一个循环内为一批用户调用该过程,那么当您扩展为大数字时,这样做将极大地有助于提高性能。

答案 3 :(得分:0)

我认为为此编写动态sql将是一个不错的选择。

import wx
import thread
import threading
import time

class ExamplePanel(wx.Panel):        
    def __init__(self, parent):
        wx.Panel.__init__(self, parent)
        self.quote = wx.StaticText(self, label="Your Log :", pos=(10, 10))

        self.logger = wx.TextCtrl(self, pos=(0,40), size=(1100,1100), style=wx.TE_MULTILINE | wx.TE_READONLY)

    def append_txt(self,txt):
        self.logger.AppendText(txt)

def sample_Window():
    app = wx.App(False)
    frame = wx.Frame(None)
    panel = ExamplePanel(frame)
    frame.Show()
    panel.append_txt("Log Starts Here\n First line of code \n Second line of code ")

    ############################################################################
    # Use thread to update logs
    ############################################################################
    task_thread = threading.Thread(target=my_task, args=(panel, ))
    task_thread.setDaemon(True)
    task_thread.start()

    app.MainLoop()

def my_task(panel):
    ############################################################################
    #  Do your job right here and update log
    ############################################################################
    for i in range(100):
        panel.append_txt('\nNew line added(No.%s)' % (i + 1))

        time.sleep(1)

sample_Window()

答案 4 :(得分:0)

即使我们能够在单个查询中实现或条件,但在性能方面可能不是那么好主意,动态sql可能是更好的选择。如果您希望提高代码效率,可能需要查看类似于https://www.youtube.com/watch?v=rWEqO-GpJ4M

的内容