PL/SQL 新手 - 返回多个结果集问题

发布于 2024-10-22 14:36:15 字数 908 浏览 4 评论 0原文

好的 - 我对 SQL Server 有相当广泛的背景,但之前我只接触过 Oracle。好吧,推已经到了紧要关头,我需要创建一个相对复杂的查询。本质上,它在 T-SQL 中归结为:

SELECT Col1 
INTO #tmpTable
FROM Table1
WHERE Col3 = @paramValue

SELECT Col1
FROM #tmpTable

SELECT OtherCol
FROM Table2
INNER JOIN #tmpTable 
  ON Table1.Col1 = Table2.fkCol1

这个序列的原因是因为对 Table1 的初始调用非常繁重(大约 5 秒的运行时间),因为它是针对我们的数据仓库的高度复杂的调用。我想在单独的调用中返回 Table2 的结果,因为 Table2 中可能有 5-10 条记录对应 Table1 中的每条记录,这使我的前端旋转更容易。

我知道我可以

SELECT Table1.Col1, Table2.OtherCol
FROM Table1
LEFT JOIN Table2 
  ON Table1.Col1 = Table2.fkCol1

在前端重新规范化数据(仅处理 Col1 的第一条记录,然后处理所有 OtherCol 记录,直到发现新的 Col1),

但我不是数据库专家,所以我不确定哪种方法更好。从开发者的角度来看,第一个解决方案对我来说更容易使用。它还(直觉)看起来性能更高,因为不必返回 Table1 与 Table2 耦合的“厚”结果。 Table1 将返回约 1200 行,宽度约 2kb。 Table2 明显更精简(约 20 字节宽),但行数更多 (6000-12000)。

所以,最终我的问题是,哪种解决方案最适合 PL/SQL 环境,如果是第一个,那么最好的解决方法是什么?全局临时表/游标/子选择/什么?

Ok - I've got quite an extensive background with SQL Server, but I've only piddled around in Oracle before. Well, push has come to shove, and I need to create a relatively complex query. Essentially, it boils down to this in T-SQL:

SELECT Col1 
INTO #tmpTable
FROM Table1
WHERE Col3 = @paramValue

SELECT Col1
FROM #tmpTable

SELECT OtherCol
FROM Table2
INNER JOIN #tmpTable 
  ON Table1.Col1 = Table2.fkCol1

The reasoning for this sequence is because the initial call to Table1 is extremely heavy (~5s runtime) because it is a highly complex call against our data warehouse. I would like to return the results from Table2 in a separate call because there are likely to be 5-10 records in Table2 for every one in Table1 and it makes my front-end pivoting easier.

I'm aware that I can do

SELECT Table1.Col1, Table2.OtherCol
FROM Table1
LEFT JOIN Table2 
  ON Table1.Col1 = Table2.fkCol1

and then re-normalize the data in the front end (processing only the first record for Col1, then all of the OtherCol records until I discover a new Col1)

I'm not a DB expert, though, so I'm not sure which is the better approach. From a dev stance, the first solution is easier for me to consume. It also (gut feeling) looks more performant, as one won't have to return the "thick" results of Table1 coupled to Table2. Table1 will be returning ~1200 rows and is ~2kb wide. Table2 is significantly leaner (~20 bytes wide) but has more rows (6000-12000).

So, ultimately my question is, which solution is the best one for a PL/SQL environment, and if it's the first one, what's the best way of going about it? Global Temporary Table / Cursor / sub select / what?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

2024-10-29 14:36:15

我会使用连接。它更容易编码和阅读,并且应该比三个单独的选择更快。如果您只选择 Col1,那么完整的行有多“粗”并不重要。

I'd use the join. It's easier to code and read and should be faster than three separate selects. And if you just select Col1 it doesn't matter how "thick" a complete row is.

街角卖回忆 2024-10-29 14:36:15

如果您担心性能,您应该测试它并比较结果。我个人会选择加入解决方案。 Oracle 将在幕后完成工作,并可能提高您的性能。

您还应该查看查询的执行计划。我确信您的开发环境可以让您快速看到执行计划。查询的成本会让您很好地了解正在发生的情况,并帮助您做出决定。

If you are worried about performance, you should just test it and compare the results. I'd personally go with the join solution. Oracle will do its thing behind the scenes and probably improve your performance.

You should also check out the Execution Plans for the queries. I'm sure that your development environment allows you to see the execution plan quickly. The cost of your queries will give you a good idea of what's happening, and will help you decide.

挽清梦 2024-10-29 14:36:15

回应您关于不知道如何实现第一个解决方案的评论:

procedure get_data(p_paramValue in varchar2, 
                  c_data1 out sys_refcursor,
                  c_data2 out sys_refcursor)
is
  v_tmptable in varchar2(30);
begin
  SELECT Col1 INTO v_tmpTable
  FROM Table1
  WHERE Col3 = p_paramValue;

  open c_data1 for 'SELECT Col1 FROM '||v_temptable;

  open c_data2 for
    'SELECT OtherCol FROM Table2 INNER JOIN '||v_tmpTable|| 
    ' ON Table1.Col1 = Table2.fkCol1'; 
end get_data;

假设 Table1.Col1 中的数据是可信的,因为两个游标中都存在注入漏洞。

In reponse to your comment about not knowing how to implement the first solution:

procedure get_data(p_paramValue in varchar2, 
                  c_data1 out sys_refcursor,
                  c_data2 out sys_refcursor)
is
  v_tmptable in varchar2(30);
begin
  SELECT Col1 INTO v_tmpTable
  FROM Table1
  WHERE Col3 = p_paramValue;

  open c_data1 for 'SELECT Col1 FROM '||v_temptable;

  open c_data2 for
    'SELECT OtherCol FROM Table2 INNER JOIN '||v_tmpTable|| 
    ' ON Table1.Col1 = Table2.fkCol1'; 
end get_data;

Assuming data in Table1.Col1 is trusted, since there is an injection vulnerability in both cursors.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文