Oracle表变量

时间:2017-04-18 17:42:22

标签: oracle plsql

使用Oracle PL / SQL是否有以下一组T-SQL语句的简单等价物?似乎我发现的所有内容要么已经过时了,要么填充表数据类型,除了将值写入stdout之外没有解释如何使用结果。

declare @tempSites table (siteid int) 

insert into @tempSites select siteid from site where state = 'TX'

if 10 > (select COUNT(*) from @tempSites)
begin 
    insert into @tempSites select siteid from site where state = 'OK'
end

select * from @tempSites ts inner join site on site.siteId = ts.siteId

正如@AlexPoole在评论中指出的那样,这是一个相当人为的例子。 我试图做的是让所有符合一定条件的网站,如果没有足够的匹配,那么我希望使用一组不同的标准。

1 个答案:

答案 0 :(得分:1)

Oracle没有本地临时表,全局临时表在这里看起来不合适。

您可以使用公用表表达式(subquery factoring):

with tempSites (siteId) as (
  select siteid
  from site
  where state = 'TX'
  union all
  select siteid
  from site
  where state = 'OK'
  and (select count(*) from site where state = 'TX') < 10
)
select s.*
from tempSites ts
join site s on s.siteid = ts.siteid;

这不是完全相同的事情,但是获取所有TX ID,并且如果必须重复的TX数量小于10,则仅包括OK值。然后加入CTE回到原来的桌子,这似乎有点浪费;你三次击中同一张桌子。

您可以直接在过滤器中使用子查询:

select *
from site
where state = 'TX'
or (state = 'OK'
  and (select count(*) from site where state = 'TX') < 10);

但是,必须再次检索(或至少计算)TX站点。

你可以使用内联视图(或者你喜欢的CTE)使用分析计数来执行此操作,这可以将TX行的数量添加到实际表中的列中,因此您可以使用d可能想要从最终结果集中排除那个虚拟列(但是使用*是不好的做法):

select *    -- but list columns, excluding tx_count
from (
  select s.*,
    count(case when state = 'TX' then state end) over (partition by null) as tx_count
  from site s
  where s.state in ('TX', 'OK')
)
where state = 'TX'
or (state = 'OK' and tx_count < 10);

根据您对研究的描述,这听起来像您正在查看填充集合的PL / SQL代码,您仍然可以这样做,但除非您的实际情况很多,否则它可能过度杀伤更复杂。