3.2.10.1. PostgreSQL

3.2.10.1.1. 空串处理兼容Oracle

PostgreSQL在处理空串’’时,并不能与Oracle保持一致,在Oracle中,空串’’会被视为NULL,但是在PostgreSQL中,空串’’会被视为空串。因此统一SQL作了如下支持:

  • 当使用XXX IS NULL时,会改写为unisql.emptystr2null(XXX) IS NULL,函数unisql.emptystr2null在输入空串时会返回NULL。

  • 当使用函数NVL,DECODE,TRIM,LPAD,RPAD,INSTR,LENGTH,LENGTHB,TO_NUMBER,COALESCE,REGEX_INSTR时(函数列表1),会对这些函数入参为列名,函数时进行CASE WHEN处理,当满足空串时会返回NULL。

警告

  1. XXX IS NULL时,当XXX为参数unisql.ora2pg.isnull.strfunlist中配置的函数时,会改写为unisql.emptystr2null(XXX) IS NULL

  2. XXX IS NULL时,当XXX为列名时,会改写为unisql.emptystr2null(XXX) IS NULL

  3. XXX IS NULL时,当XXX为二元表达式时,会改写为unisql.emptystr2null(XXX) IS NULL

  4. XXX IS NULL时,当XXX为’’时,会改写为NULL

  5. XXX IS NULL时,当CAST(‘’ AS TP)时,会改写为CAST(NULL AS TP) IS NULL

  6. 针对函数列表1,当入参为函数时,会改写为CASE CAST(函数 AS text) WHEN ‘’ THEN NULL ELSE 函数 END

  7. 针对函数列表1,当入参为列名时,会改写为CASE CAST(列名 AS text) WHEN ‘’ THEN NULL ELSE 列名 END

  8. 针对函数列表1,当入参为’’时, 会改写为NULL

  9. 针对函数列表1,当入参为CAST(‘’ AS TP)时, 会直接改写为CAST(NULL AS TP)

  10. Oracle和PostgreSQL在处理CHAR(N)存在差异,在Oracle中,CHAR(N)会将N个字节的空间填充为空格,但是会视为有效空格,在PostgreSQL中则视为空串,因此也会被当做NULL处理掉。

示例

-- 转换前 Oracle SQL:
SELECT id, unique_col
    FROM null_test_tab
WHERE CONCAT(varchar_col, varchar2_col) IS NULL

-- 转换后 POSTGRESQL SQL:
SELECT id, unique_col
    FROM null_test_tab
WHERE unisql.emptystr2null(CONCAT(varchar_col, varchar2_col)) IS NULL

-- 转换前 Oracle SQL:
select length(''), length(null), length('abc')
    , length(' abc ') , length('张三'), length(123)
    , length(0123), length('abc' || 'abc')
from dual;
-- 转换后 POSTGRESQL SQL:
SELECT length(CAST(NULL AS text)), length(CAST(NULL AS text)), length(CAST('abc' AS text))
    ,length(CAST(' abc ' AS text)), length(CAST('张三' AS text)), length(CAST(123 AS text))
    , length(CAST(123 AS text)), length(CAST(concat('abc', 'abc') AS text));

-- 转换前 Oracle SQL:
select id, length(num_col), length(int_col), length(varchar_col), length(varchar2_col)
    from null_test_tab order by id asc;
-- 转换后 POSTGRESQL SQL:
SELECT id, length(CAST(CASE CAST(num_col AS text) WHEN '' THEN NULL ELSE num_col END AS text))
    ,length(CAST(CASE CAST(int_col AS text) WHEN '' THEN NULL ELSE int_col END AS text))
    ,length(CAST(CASE CAST(varchar_col AS text) WHEN '' THEN NULL ELSE varchar_col END AS text))
    ,length(CAST(CASE CAST(varchar2_col AS text) WHEN '' THEN NULL ELSE varchar2_col END AS text))
    FROM null_test_tab ORDER BY id;