如何根据 Oracle 中的动态列表检查 IN 条件?

发布于 2024-09-13 22:06:19 字数 620 浏览 1 评论 0原文

编辑:更改标题以适合下面的代码。

我试图从 Oracle 表中检索可接受值的列表,然后对另一个表执行 SELECT,同时将某些字段与所述列表进行比较。

我试图用光标来做到这一点(如下所示),但是失败了。

DECLARE
    TYPE gcur IS REF CURSOR;
    TYPE list_record IS TABLE OF my_table.my_field%TYPE;
    c_GENERIC gcur;
    c_LIST list_record;
BEGIN
    OPEN c_GENERIC FOR
    SELECT my_field FROM my_table
    WHERE some_field = some_value;

    FETCH c_GENERIC BULK COLLECT INTO c_LIST;

    -- try to check against list
    SELECT * FROM some_other_table
    WHERE some_critical_field IN c_LIST;

END

基本上,我想做的是将可接受的值列表缓存到变量中,因为稍后我将反复检查它。

在 Oracle 中如何执行此操作?

EDIT: changed the title to fit the code below.

I'm trying to retrieve a list of acceptable values from an Oracle table, then performing a SELECT against another while comparing some fields against said list.

I was trying to do this with cursors (like below), but this fails.

DECLARE
    TYPE gcur IS REF CURSOR;
    TYPE list_record IS TABLE OF my_table.my_field%TYPE;
    c_GENERIC gcur;
    c_LIST list_record;
BEGIN
    OPEN c_GENERIC FOR
    SELECT my_field FROM my_table
    WHERE some_field = some_value;

    FETCH c_GENERIC BULK COLLECT INTO c_LIST;

    -- try to check against list
    SELECT * FROM some_other_table
    WHERE some_critical_field IN c_LIST;

END

Basically, what I'm trying to do is to cache the acceptable values list into a variable, because I will be checking against it repeatedly later.

How do you perform this in Oracle?

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

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

发布评论

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

评论(2

随波逐流 2024-09-20 22:06:19

我们可以使用集合来存储值来满足您的目的,但它们需要声明为 SQL 类型:

create type list_record is table of varchar2(128)
/

这是因为我们不能在 SQL 语句中使用 PL/SQL 类型。唉,这意味着我们不能使用 %TYPE%ROWTYPE,因为它们是 PL/SQL 关键字。

您的程序将如下所示:

DECLARE
    c_LIST list_record;
BEGIN

    SELECT my_field 
    BULK COLLECT INTO c_LIST 
    FROM my_table
    WHERE some_field = some_value;

    -- try to check against list
    SELECT * FROM some_other_table
    WHERE some_critical_field IN ( select * from table (c_LIST);

END;    

“我发现你仍然需要执行
用于填充列表的 SELECT 语句
对于 IN 子句。”

如果值在表中,则没有其他方法可以将它们放入变量中:)

“我认为有一个
使用显着的性能增益
这是通过直接半连接实现的”

不一定。如果您只使用这些值一次,那么子查询肯定是更好的方法。但是当您想在多个离散查询中使用相同的值时,然后填充一个集合是更有效的方法,

在 11g 企业版中,我们可以选择使用结果集缓存。 这是一种更好的解决方案,但并不适合所有表。

We can use collections to store values to suit your purposes, but they need to be declared as SQL types:

create type list_record is table of varchar2(128)
/

This is because we cannot use PL/SQL types in SQL statements. Alas this means we cannot use %TYPE or %ROWTYPE, because they are PL/SQL keywords.

Your procedure would then look like this:

DECLARE
    c_LIST list_record;
BEGIN

    SELECT my_field 
    BULK COLLECT INTO c_LIST 
    FROM my_table
    WHERE some_field = some_value;

    -- try to check against list
    SELECT * FROM some_other_table
    WHERE some_critical_field IN ( select * from table (c_LIST);

END;    

"I see that you still had to perform a
SELECT statement to populate the list
for the IN clause."

If the values are in a table there is no other way to get them into a variable :)

"I'm thinking that there's a
significant performance gain using
this over a direct semi-join"

Not necessarily. If you're only using the values once then the sub-query is certainly the better approach. But as you want to use the same values in a number of discrete queries then populating a collection is the more efficient approach.

In 11g Enterprise Edition we have the option to use result set caching. This is a much better solution, but one which is not suited for all tables.

那片花海 2024-09-20 22:06:19

为什么拉列表而不是使用半连接?

SELECT * 
  FROM some_other_table 
 WHERE some_critical_field IN (SELECT my_field 
                                FROM my_table
                               WHERE some_field = some_value); 

Why pull the list instead of using a semi-join?

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