首页 \ 问答 \ Oracle SQL:在'WITH'语句中,如何进行条件选择,使用IF还是CASE?(Oracle SQL: in 'WITH' statement, how to do conditional select, use IF or CASE?)

Oracle SQL:在'WITH'语句中,如何进行条件选择,使用IF还是CASE?(Oracle SQL: in 'WITH' statement, how to do conditional select, use IF or CASE?)

我有两张桌子:

CREATE TABLE Test_Persons_A (
    PersonID int,
    LastName varchar(255),
    FirstName varchar(255)
);

INSERT INTO Test_Persons_A
    (PersonID,LastName,FirstName)
    values(11,'LN_A1','FN_A1');

INSERT INTO Test_Persons_A
    (PersonID,LastName,FirstName)
    values(12,'LN_A2','FN_A2');

CREATE TABLE Test_Persons_B (
    PersonID int,
    LastName varchar(255),
    FirstName varchar(255)
);

INSERT INTO Test_Persons_B
    (PersonID,LastName,FirstName)
    values(21,'LN_B1','FN_B1');

INSERT INTO Test_Persons_B
    (PersonID,LastName,FirstName)
    values(22,'LN_B2','FN_B2');

commit;

但后来我无法弄清楚如何对后面的'WITH'进行条件选择:

------------------------------use IF, not working ------------------------------
var TEST_TBL varchar2(20);
exec :TEST_TBL := 'test_person_A';

with Test_tbl as
(
    IF UPPER(:TEST_TBL) = 'TEST_PERSONS_A' then select * from Test_Persons_A;
    ELSIF UPPER(:TEST_TBL) = 'TEST_PERSONS_B' then select * from Test_Persons_B;
    End if;
)

select PersonID as PID, LastName as LN, FirstName as FN
    from Test_tbl tp
    where tp.LASTNAME like '%1%'

------------------------------use CASE, not working ------------------------------
var TEST_TBL varchar2(20);
exec :TEST_TBL := 'test_person_A';

with Test_tbl as
(
    CASE WHEN UPPER(:TEST_TBL) = 'TEST_PERSONS_A' then 
        select * from Test_Persons_A;
    ELSE 
        select * from Test_Persons_B;
    End
)
select PersonID as PID, LastName as LN, FirstName as FN
    from Test_tbl tp
    where tp.LASTNAME like '%1%';

最终,我能以某种方式推广这个吗? 即在SQL(至少oracle)哪里可以断言条件语句,哪里不能?


I have two tables:

CREATE TABLE Test_Persons_A (
    PersonID int,
    LastName varchar(255),
    FirstName varchar(255)
);

INSERT INTO Test_Persons_A
    (PersonID,LastName,FirstName)
    values(11,'LN_A1','FN_A1');

INSERT INTO Test_Persons_A
    (PersonID,LastName,FirstName)
    values(12,'LN_A2','FN_A2');

CREATE TABLE Test_Persons_B (
    PersonID int,
    LastName varchar(255),
    FirstName varchar(255)
);

INSERT INTO Test_Persons_B
    (PersonID,LastName,FirstName)
    values(21,'LN_B1','FN_B1');

INSERT INTO Test_Persons_B
    (PersonID,LastName,FirstName)
    values(22,'LN_B2','FN_B2');

commit;

But then I can't figure out how to do a conditional select for the 'WITH' that follows:

------------------------------use IF, not working ------------------------------
var TEST_TBL varchar2(20);
exec :TEST_TBL := 'test_person_A';

with Test_tbl as
(
    IF UPPER(:TEST_TBL) = 'TEST_PERSONS_A' then select * from Test_Persons_A;
    ELSIF UPPER(:TEST_TBL) = 'TEST_PERSONS_B' then select * from Test_Persons_B;
    End if;
)

select PersonID as PID, LastName as LN, FirstName as FN
    from Test_tbl tp
    where tp.LASTNAME like '%1%'

------------------------------use CASE, not working ------------------------------
var TEST_TBL varchar2(20);
exec :TEST_TBL := 'test_person_A';

with Test_tbl as
(
    CASE WHEN UPPER(:TEST_TBL) = 'TEST_PERSONS_A' then 
        select * from Test_Persons_A;
    ELSE 
        select * from Test_Persons_B;
    End
)
select PersonID as PID, LastName as LN, FirstName as FN
    from Test_tbl tp
    where tp.LASTNAME like '%1%';

And ultimately, can I generalize this somehow? i.e. In SQL (oracle at least) where can I assert conditional statements, and where can't I?


原文:https://stackoverflow.com/questions/51330449
更新时间:2021-11-18 07:11

最满意答案

您没有执行任何查询。 您只是将查询字符串分配给返回的结果变量。 我没有尝试编译它,但是这样的事情:

    create or replace function update_grade(nm number) return varchar2
    as
    grd varchar2(3);
    begin
    SELECT gradeid  INTO grd from grade where nm between marks_s and markks_e;
    return grd;
    end;

如果没有找到数据,您可以考虑为案例添加处理:

   EXCEPTION
      WHEN NO_DATA_FOUND THEN
        grd:= NULL;

You are not executing any query. You are just assigning the query string to the returned result variable. I've not tried to compile it, but something like this:

    create or replace function update_grade(nm number) return varchar2
    as
    grd varchar2(3);
    begin
    SELECT gradeid  INTO grd from grade where nm between marks_s and markks_e;
    return grd;
    end;

You might consider adding handling for the case when no data is found:

   EXCEPTION
      WHEN NO_DATA_FOUND THEN
        grd:= NULL;

相关问答

更多
  • INTERVAL不是一个函数,它是一个引入间隔字面值的关键字,而这个表示数据类型 。 类似于文字TIMESTAMP '2011-05-04 17:18:19'或TIMESTAMP '2011-05-04 17:18:19'正在做的事情。 有关区间文字的详细信息 http://docs.oracle.com/cd/E11882_01/server.112/e41084/sql_elements003.htm#SQLRF00221 http://docs.oracle.com/cd/E11882_01/serv ...
  • 以下是Oracle文档中的一个示例。 基本上你需要dbms_sql.fetch_rows和dbms_sql.column_value : CREATE TABLE multi_tab (num NUMBER, dat1 DATE, var VARCHAR2(24), dat2 DATE) declare c NUMBER; d ...
  • 您没有执行任何查询。 您只是将查询字符串分配给返回的结果变量。 我没有尝试编译它,但是这样的事情: create or replace function update_grade(nm number) return varchar2 as grd varchar2(3); begin SELECT gradeid INTO grd from grade where nm between marks_s and markks_e; return grd; ...
  • 你已经混淆了你的代码,我怀疑这个过程中隐藏了问题。 我怀疑你的代码更像 create or replace FUNCTION FUNC_FAAL(myNumberColumn number,firstDate date , secondDate date) RETURN INTEGER as rtr integer; BEGIN select count(*) into rtr from my_table tbl where tbl.myDateColumn between fir ...
  • 您需要在子查询周围放置括号: select replace ((SELECT TO_CHAR(CURRENT_TIMESTAMP) FROM DUAL),CURRENT_TIMESTAMP,'2015-03-10 11:45:15') As result from dual; 但是,写得很糟糕。 您的TO_CHAR(CURRENT_TIMESTAMP)没有格式掩码,这意味着您将时间戳转换为字符串依赖于您的nls设置。 这是不好的做法。 此外,replace语句的第二个参数中的CURRENT_TIMESTA ...
  • 正如Yahia指出的,您应该始终使用绑定变量而不是动态地动态组装SQL语句。 这是保护自己免受SQL注入攻击的正确方法。 转义字符串提供了更低的保护级别。 话虽如此,假设您使用Oracle 10.1或更高版本,则可以使用q引用语法。 就像是 1 select q'[This is a string with an embedded ']' str 2* from dual SQL> / STR ----------------------------------- This is a str ...
  • 我之前看过上一篇文章时曾尝试过。 但是,当我编写SQL时,我包含了包装版本,这就是导致异常的原因,即包装的sql。 如果SQL编写如下,它可以完美地工作。 public string UpdateParticipant(ParticipantUpdate Participant) { string ret = ""; IsoDateTimeConverter dt = new IsoDateTimeConverter(); dt.DateTimeFormat = "MM-dd-yyy ...
  • 字符串比较基于字母顺序。 字符串M9W在M9W0A0和M9W9Z9之间不是按字母顺序排列的。 按字母顺序排在两者之前。 按字母顺序,它出现在任何字符串M9W<> 。 String comparison is based on alphabetical order. The string M9W is not alphabetically between M9W0A0 and M9W9Z9. Alphabetically, it comes before both ...
  • 您可以EXECUTE IMMEDIATE INTO变量并在条件语句中使用它。 下面的示例是一个函数,其输入是SELECT COUNT(*)类型的查询字符串,如果计数> 0,则其输出为TRUE 。 首先创建一个测试表: CREATE TABLE MYTABLE(X NUMBER); INSERT INTO MYTABLE VALUES (1); 然后创建包: CREATE PACKAGE MYPACKAGE AS FUNCTION DOES_IT_EXIST(QUERY_STRING IN VARCHA ...
  • 您的函数返回一个sys_refcursor并在您的代码中返回一个simple cursor 。 这使代码错误。 如果要从函数返回ref_cursor ,可以使用如下: create or replace function stuff (p_var number) return sys_refcursor is rf_cur sys_refcursor; begin open rf_cur for select * from employee w ...

相关文章

更多

最新问答

更多
  • 您如何使用git diff文件,并将其应用于同一存储库的副本的本地分支?(How do you take a git diff file, and apply it to a local branch that is a copy of the same repository?)
  • 将长浮点值剪切为2个小数点并复制到字符数组(Cut Long Float Value to 2 decimal points and copy to Character Array)
  • OctoberCMS侧边栏不呈现(OctoberCMS Sidebar not rendering)
  • 页面加载后对象是否有资格进行垃圾回收?(Are objects eligible for garbage collection after the page loads?)
  • codeigniter中的语言不能按预期工作(language in codeigniter doesn' t work as expected)
  • 在计算机拍照在哪里进入
  • 使用cin.get()从c ++中的输入流中丢弃不需要的字符(Using cin.get() to discard unwanted characters from the input stream in c++)
  • No for循环将在for循环中运行。(No for loop will run inside for loop. Testing for primes)
  • 单页应用程序:页面重新加载(Single Page Application: page reload)
  • 在循环中选择具有相似模式的列名称(Selecting Column Name With Similar Pattern in a Loop)
  • System.StackOverflow错误(System.StackOverflow error)
  • KnockoutJS未在嵌套模板上应用beforeRemove和afterAdd(KnockoutJS not applying beforeRemove and afterAdd on nested templates)
  • 散列包括方法和/或嵌套属性(Hash include methods and/or nested attributes)
  • android - 如何避免使用Samsung RFS文件系统延迟/冻结?(android - how to avoid lag/freezes with Samsung RFS filesystem?)
  • TensorFlow:基于索引列表创建新张量(TensorFlow: Create a new tensor based on list of indices)
  • 企业安全培训的各项内容
  • 错误:RPC失败;(error: RPC failed; curl transfer closed with outstanding read data remaining)
  • C#类名中允许哪些字符?(What characters are allowed in C# class name?)
  • NumPy:将int64值存储在np.array中并使用dtype float64并将其转换回整数是否安全?(NumPy: Is it safe to store an int64 value in an np.array with dtype float64 and later convert it back to integer?)
  • 注销后如何隐藏导航portlet?(How to hide navigation portlet after logout?)
  • 将多个行和可变行移动到列(moving multiple and variable rows to columns)
  • 提交表单时忽略基础href,而不使用Javascript(ignore base href when submitting form, without using Javascript)
  • 对setOnInfoWindowClickListener的意图(Intent on setOnInfoWindowClickListener)
  • Angular $资源不会改变方法(Angular $resource doesn't change method)
  • 在Angular 5中不是一个函数(is not a function in Angular 5)
  • 如何配置Composite C1以将.m和桌面作为同一站点提供服务(How to configure Composite C1 to serve .m and desktop as the same site)
  • 不适用:悬停在悬停时:在元素之前[复制](Don't apply :hover when hovering on :before element [duplicate])
  • 常见的python rpc和cli接口(Common python rpc and cli interface)
  • Mysql DB单个字段匹配多个其他字段(Mysql DB single field matching to multiple other fields)
  • 产品页面上的Magento Up出售对齐问题(Magento Up sell alignment issue on the products page)