在 Oracle(11.2 之前)中:使用cast(collect(...)) 时,如何对结果排序?
使用cast(collect(...))时,如何排序结果?
我有一个名为 GetStringForTable 的函数,定义如下:
FUNCTION GetStringForTable(vTable in TVarCharTable, vDelimeter in varchar default ',') return VarChar2 is
aResult varchar2(32767);
i int;
begin
if vTable.count = 0 then
return '';
end if;
for i in 1 .. vTable.Count loop
if i > 1 then
aResult := aResult || vDelimeter;
end if;
aResult := aResult || vTable(i);
end loop;
return aResult;
end GetStringForTable;
我这样使用它:
select
name,
rep.GetStringForTable
((
Select
cast(collect(name) as TVarCharTable)
from
contacts
where
debtoraccount = dt.accountnumber
)
,', ' --Delimiter
) "Contacts"
from debtable dt
where name like '%Svein%';
问题是结果没有排序。当我想要“Alice、Bob、Carol、Dave”时,我会得到“Dave、Bob、Carol、Alice”。我如何订购结果?如果尝试以下操作,但没有任何效果:
select
name,
rep.GetStringForTable
((
Select
cast(collect(name) as TVarCharTable)
from
contacts
where
debtoraccount = dt.accountnumber
order by name <= ORA-00907: missing right parenthesis
)
,', ' --Skilletegn
) "Contacts"
from debtable dt
where name like '%Svein%';
理想
select
name,
rep.GetStringForTable
((
select * from
(
Select
cast(collect(name) as TVarCharTable)
from
contacts
where
debtoraccount = dt.accountnumber <= ORA-00904: string: invalid identifier
order by name
)
)
,', ' --Skilletegn
) "Contacts"
from debtable dt
where name like '%Svein%';
情况下,我想在不更改 GetStringForTable 函数的情况下进行排序。
有人可以帮忙吗?
When using cast(collect(...)), how do I order the result?
I have a function called GetStringForTable, defined like this:
FUNCTION GetStringForTable(vTable in TVarCharTable, vDelimeter in varchar default ',') return VarChar2 is
aResult varchar2(32767);
i int;
begin
if vTable.count = 0 then
return '';
end if;
for i in 1 .. vTable.Count loop
if i > 1 then
aResult := aResult || vDelimeter;
end if;
aResult := aResult || vTable(i);
end loop;
return aResult;
end GetStringForTable;
And I use it like this:
select
name,
rep.GetStringForTable
((
Select
cast(collect(name) as TVarCharTable)
from
contacts
where
debtoraccount = dt.accountnumber
)
,', ' --Delimiter
) "Contacts"
from debtable dt
where name like '%Svein%';
The problem is that the result is not ordered. I get "Dave, Bob, Carol, Alice" when I would like "Alice, Bob, Carol, Dave". How do I order the result? If tried the following, but none works:
select
name,
rep.GetStringForTable
((
Select
cast(collect(name) as TVarCharTable)
from
contacts
where
debtoraccount = dt.accountnumber
order by name <= ORA-00907: missing right parenthesis
)
,', ' --Skilletegn
) "Contacts"
from debtable dt
where name like '%Svein%';
and
select
name,
rep.GetStringForTable
((
select * from
(
Select
cast(collect(name) as TVarCharTable)
from
contacts
where
debtoraccount = dt.accountnumber <= ORA-00904: string: invalid identifier
order by name
)
)
,', ' --Skilletegn
) "Contacts"
from debtable dt
where name like '%Svein%';
Ideally,I would like to do the ordering without changing the GetStringForTable-function.
Can anyone help?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
此语法首次在 11gR1 手册中提到。但它似乎在 10g 上工作得很好,即使它不是 已记录。
This syntax is first mentioned in the 11gR1 manual. But it seems to work fine with 10g even though it is not documented.
一种方法是修改 GetStringForTable ,以便输出是有序的(您可以有两个函数:一个是有序的,另一个不是)
更新
我找到了一种解决方法,但不幸的是,在额外的测试中,不能保证顺序。它将取决于所选择的访问路径。不过,它可能适用于您的情况:
您可以通过某种技巧强制 ORDER 来具体化子查询,但这会阻止优化器使用大多数有效路径,例如:
one method would be to modify GetStringForTable so that the output comes ordered (you could have two functions: one ordered and the other not)
Update
I've found a workaround, but unfortunately upon additional tests the ORDER is not guaranteed. It will depend upon the access path chosen. Still, it may work in your case :
You can sort of force the ORDER with a trick to materialize the subquery, but this would prevent the optimizer from using most of the efficient paths, for example: