sql >> データベース >  >> RDS >> PostgreSQL

PL/pgSQLを使用してPostgreSQLのレコードとして複数のフィールドを返します

    多態的な結果を返すためにCREATETYPEを使用しないでください。代わりに、RECORDタイプを使用して悪用してください。チェックしてください:

    CREATE FUNCTION test_ret(a TEXT, b TEXT) RETURNS RECORD AS $$
    DECLARE 
      ret RECORD;
    BEGIN
      -- Arbitrary expression to change the first parameter
      IF LENGTH(a) < LENGTH(b) THEN
          SELECT TRUE, a || b, 'a shorter than b' INTO ret;
      ELSE
          SELECT FALSE, b || a INTO ret;
      END IF;
    RETURN ret;
    END;$$ LANGUAGE plpgsql;
    

    オプションで2つを返すことができるという事実に注意してください または3つ 入力に応じて列。

    test=> SELECT test_ret('foo','barbaz');
                 test_ret             
    ----------------------------------
     (t,foobarbaz,"a shorter than b")
    (1 row)
    
    test=> SELECT test_ret('barbaz','foo');
                 test_ret             
    ----------------------------------
     (f,foobarbaz)
    (1 row)
    

    これはコードに大混乱をもたらすので、一貫した数の列を使用しますが、最初のパラメーターが操作の成功を返すオプションのエラーメッセージを返すのに非常に便利です。一定数の列を使用して書き直されました:

    CREATE FUNCTION test_ret(a TEXT, b TEXT) RETURNS RECORD AS $$
    DECLARE 
      ret RECORD;
    BEGIN
      -- Note the CASTING being done for the 2nd and 3rd elements of the RECORD
      IF LENGTH(a) < LENGTH(b) THEN
          ret := (TRUE, (a || b)::TEXT, 'a shorter than b'::TEXT);
      ELSE
          ret := (FALSE, (b || a)::TEXT, NULL::TEXT);
       END IF;
    RETURN ret;
    END;$$ LANGUAGE plpgsql;
    

    ほぼ壮大な暑さ:

    test=> SELECT test_ret('foobar','bar');
       test_ret    
    ----------------
     (f,barfoobar,)
    (1 row)
    
    test=> SELECT test_ret('foo','barbaz');
                 test_ret             
    ----------------------------------
     (t,foobarbaz,"a shorter than b")
    (1 row)
    

    しかし、それを複数の行に分割して、選択したORMレイヤーが値を選択した言語のネイティブデータ型に変換できるようにするにはどうすればよいでしょうか。暑さ:

    test=> SELECT a, b, c FROM test_ret('foo','barbaz') AS (a BOOL, b TEXT, c TEXT);
     a |     b     |        c         
    ---+-----------+------------------
     t | foobarbaz | a shorter than b
    (1 row)
    
    test=> SELECT a, b, c FROM test_ret('foobar','bar') AS (a BOOL, b TEXT, c TEXT);
     a |     b     | c 
    ---+-----------+---
     f | barfoobar | 
    (1 row)
    

    これは、PostgreSQLで最もクールで最も使用されていない機能の1つです。言葉を広めてください。



    1. SQLエラー:ORA-00942テーブルまたはビューが存在しません

    2. SQLServerからOracleへのデータの繰り返しの移動

    3. mysqlのテーブルから重複する行を削除する方法

    4. NULL列に一意のインデックスを作成するにはどうすればよいですか?