4

我有一个存储函数,它应该比较三个文本值是否相等。其中一些文本值可能为空,如果是,则比较应返回假值。

CREATE OR REPLACE FUNCTION "subject_check_if_subjectName_exists"(name1IN text, name2IN text, name3IN text, name4IN text)
returns boolean as
$$
declare
    results boolean;
    subjectList record;
begin
    results = false;
    for subjectList in select name1, name2, name3, name4 from subject loop
    if (name1In = subjectList.name1) and (name2In = subjectList.name2) and (name3In = subjectList.name3) and (name4In = subjectList.name4)
      then
        results = true;
        EXIT; -- exit out of loop
    end if;
    end loop;
    return results;
end;
$$ language 'plpgsql';

name4IN 和 subjectList.name4 都为 null,并且所有其他值都相等,该函数不返回真值 - 它应该返回。即使它们为空(null = null 应该返回 true),我如何比较这些文本值?

4

3 回答 3

6

我想你想使用is not distinct from

对于非空输入,IS DISTINCT FROM与运算符相同<>。但是,如果两个输入都为 null,则返回 false,如果只有一个输入为 null,则返回 true。类似地,对于非空输入,它IS NOT DISTINCT FROM与 相同,但是当两个输入都为空时它返回真,当只有一个输入为空时它返回假。=

从本质上讲,A is not distinct from B就像A = B但它将 NULL 视为“相等”(即,它的行为就像大多数 SQL 新手认为=应该的那样)。例如,考虑这样一个简单的函数:

create function f(text,text) returns text as $$
begin
    if $1 is distinct from $2 then
        return '!=';
    end if;
    return '==';
end $$
language plpgsql;

这会给你这样的结果:

=> select f(null, null) as "1"
          f(null, '') as "2",
          f('', '') as "3",
          f('pancakes','pancakes') as "4",
          f('pancakes', null) as "5",
          f('pancakes', 'house') as "6";
 1  | 2  | 3  | 4  | 5  | 6  
----+----+----+----+----+----
 == | != | == | == | != | !=

因此,您正在寻找这样的东西:

if (name1In is not distinct from subjectList.name1) and ...
于 2012-06-19T07:12:45.290 回答
0

使用合并:

if (coalesce(name1In, '') = coalesce(subjectList.name1, '') ....
于 2012-06-19T06:55:35.560 回答
0

本质上,这就是我想要做的。我认为必须有一种更快的方法来比较包括空值在内的值。这就是我想要它做的事情:

-- Function to check subject names (name1,2,3 and 4) already exists
CREATE OR REPLACE FUNCTION "subject_check_if_subjectName_exists"(name1IN text, name2IN text, name3IN text, name4IN text)
returns boolean as
$$
declare
    results boolean;
    subjectList record;
begin
    results = false;
    for subjectList in select name1, name2, name3, name4 from subject loop
    if ((subjectList.name4 is null) and (name4IN is null)) then
        if ((subjectList.name3 is null) and (name3IN is null)) then
        if ((subjectList.name2 is null) and (name2IN is null)) then
          if (name1IN = subjectList.name1) then
            results = true;
            EXIT;
          end if;
        else
          if ((name1IN = subjectList.name1) and (name2IN = subjectList.name2)) then
            results = true;
            EXIT;
          end if;
        end if;
        else
          if ((name1IN = subjectList.name1) and (name2IN = subjectList.name2) and (name3IN = subjectList.name3)) then
        results = true;
        EXIT;
          end if;
        end if;
    else
      if ((name1IN = subjectList.name1) and (name2IN = subjectList.name2) and (name3IN = subjectList.name3) and (name4IN = subjectList.name4)) then
        results = true;
        EXIT;
          end if;
    end if;
    end loop;
    return results;
end;
$$ language 'plpgsql';

将尝试与现在不同。

感谢您的帮助。非常感激!

于 2012-06-19T07:24:44.170 回答