简体   繁体   English

WHILE / LOOP 内 CASE 表达式 SQL - ORACLE

[英]WHILE / LOOP inside CASE expression SQL - ORACLE

I am testing a select statement containing a CASE expression and I need to add a WHILE / LOOP inside one of the WHEN conditions.我正在测试一个包含 CASE 表达式的 select 语句,我需要在其中一个 WHEN 条件中添加一个 WHILE / LOOP。

The logic from this statement will eventually be included inside a PL/SQL script but I want to know it´s working 100% before I include it in the procedural.此语句的逻辑最终将包含在 PL/SQL 脚本中,但我想在将其包含在程序中之前知道它 100% 工作。

The logic serves to query a zip/postal code inside an XML package found in a clob column.该逻辑用于查询在 clob 列中找到的 XML 包内的邮政编码。

INTENDED ACTION:预期行动:

if ZIP > 5 digits then remove everything after 5th char.如果 ZIP > 5 位数字,则删除第 5 个字符后的所有内容。

if ZIP < 5 digits then add '0' until the length reaches 5 char.如果 ZIP < 5 位数字,则添加 '0' 直到长度达到 5 个字符。

else do nothing.别的什么都不做。

WHAT IS NEEDED:需要什么:

The logic that adds a '0' using contact() function needs to reiterate until the new zip reaches a length of 5 char.使用 contact() 函数添加“0”的逻辑需要重复,直到新 zip 达到 5 个字符的长度。 As it is, the query only adds up to one '0', but this needs to repeat as many times as required for total char length to = '5'.实际上,该查询加起来最多只有一个“0”,但这需要根据总字符长度为 = '5' 的需要重复多次。 My attempts at adding a LOOP or a WHILE all result in incorrect formating according to Oracle SQL.根据 Oracle SQL,我尝试添加 LOOP 或 WHILE 都会导致格式不正确。

QUERY:询问:

SELECT ORDER_NUMBER, 
EXTRACTVALUE(xmltype(PACKAGE), '/Package/fCustomerVO/invoiceAddress/zip') as "ZIPS_INV",
LENGTH(EXTRACTVALUE(xmltype(PACKAGE), '/Package/fCustomerVO/invoiceAddress/zip')) as "ZIPS_LEN",
CASE
/* add digits to zip WHILE/LOOP NEEDED HERE */
  WHEN LENGTH(EXTRACTVALUE(xmltype(PACKAGE), '/Package/fCustomerVO/invoiceAddress/zip')) < 5 
    THEN concat(EXTRACTVALUE(xmltype(PACKAGE), '/Package/fCustomerVO/invoiceAddress/zip'), '0')
/* subtract digits to zip */
  WHEN LENGTH(EXTRACTVALUE(xmltype(PACKAGE), '/Package/fCustomerVO/invoiceAddress/zip')) > 5 
    THEN substr(EXTRACTVALUE(xmltype(PACKAGE), '/Package/fCustomerVO/invoiceAddress/zip'), 1, 5)    
  ELSE 
    'correct format'
END as "FIXED_ZIP"
FROM quarantine;

You can do both operations at once with RPAD() : this functions either pads the string, truncates it or leaves it untouched as per the target length.您可以使用RPAD()一次执行这两个操作:该函数可以根据目标长度填充字符串、截断它或保持它不变。

So:所以:

RPAD(
    EXTRACTVALUE(xmltype(PACKAGE), '/Package/fCustomerVO/invoiceAddress/zip'),
    5,
    '0'
) 

In your query:在您的查询中:

SELECT
    t.*,
    LENGTH(zips_inv) zip_len,
    RPAD(zip_inv, 5, '0') fixed_zip
    CASE WHEN LENGTH(zips_inv) = 5
        THEN 'correct format'
        ELSE 'wrong format' 
    END zip_status
FROM (
    SELECT 
        order_number, 
        EXTRACTVALUE(xmltype(PACKAGE), '/Package/fCustomerVO/invoiceAddress/zip') zips_inv
    FROM quarantine
) t

I find that a subquery is useful here to avoid repeating the same lengthy expression multiple times.我发现子查询在这里很有用,可以避免多次重复相同的冗长表达式。 Also, separating the zip value from its status (correct or not) makes more sense to me.此外,将 zip 值与其状态(正确与否)分开对我来说更有意义。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM