4

3 つのテキスト値が等しいかどうかを比較するストアド関数があります。これらのテキスト値の一部は null である可能性があり、その場合、比較は false 値を返す必要があります。

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 = null は true を返す必要があります) の場合でも、どのように比較できますか?

4

3 に答える 3

6

私はあなたが使いたいと思いますis not distinct from

null以外の入力の場合、は演算子IS DISTINCT FROMと同じです。<>ただし、両方の入力がnullの場合はfalseを返し、一方の入力のみがnullの場合はtrueを返します。同様に、 null以外の入力のIS NOT DISTINCT FROM場合と同じですが=、両方の入力がnullの場合はtrueを返し、1つの入力のみがnullの場合はfalseを返します。

基本的に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

本質的に、これは私がやりたいことです。null 値を含む値を比較するためのより迅速な方法が必要であると考えました。これは私がやりたいことをします:

-- 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';

IS NOT DISTINCT FROM を試してみます。

ご協力ありがとうございました。とても有難い!

于 2012-06-19T07:24:44.170 に答える