6

昨日、PostgreSQL データベースをバージョン 9.1.3 にアップグレードしました。すべてをテストして準備ができていると思っていましたが、見落としていた機能があります。次のようなテーブル型を返します。

CREATE OR REPLACE FUNCTION myfunc( patient_number varchar
    , tumor_number_param varchar, facility_number varchar)
  RETURNS SETOF patient_for_registrar
  LANGUAGE plpgsql
AS
$body$
BEGIN
    RETURN QUERY            

    SELECT cast(nfa.patient_id_number as varchar),
    ...

エラーが発生する場所であるため、選択の最初の列のみを指定します。今日まで、この関数は正常に実行されていましたが、現在は次のエラーが発生します。

エラー: クエリの構造が関数の結果の型と一致しません
詳細: 返された型の文字の変化が、列 1 の予想される型の文字の変化 (8) と一致しません。 ]

nfa.patient_id_numberはテキストであり、その列にキャストされてpatient_id_numberpatient_for_registrarますvarchar(8)。これについて読んだ後、テキストからキャストするときに列の長さが指定されていないことが問題だと思います。しかし、問題は、これを修正するために部分文字列のさまざまな組み合わせを試しましたが、どれも問題を解決していないことです:

substring(cast(nfa.patient_id_number as varchar) from 1 for 8),

cast(substring(nfa.patient_id_number from 1 for 8) as varchar),

cast(substring(nfa.patient_id_number from 1 for 8) as varchar(8)),

誰にも指針がありますか?

4

1 に答える 1

16

あなたの機能..

RETURNS SETOF patient_for_registrar

返される行タイプは、宣言されたタイプと正確に一致する必要があります。patient_for_registrarおそらく関連するテーブルの複合タイプの定義を開示していません。複合型の宣言に関するマニュアルを引用します:

テーブルを作成するたびに、テーブルと同じ名前の複合タイプも自動的に作成され、テーブルの行タイプを表します。

そのタイプ(テーブル)の最初の列が(長さ修飾子を使用して)定義されている場合-エラーメッセージが示すように、同じ長さ修飾子を使用しvarchar(8)て戻る必要があります。しません。文字列の長さが8文字だけであるかどうかは関係ありませんが、データ型は一致する必要があります。varchar(8)varchar

varcharvarchar(n)およびvarchar(m)はPostgreSQLのさまざまなデータ型です。

古いバージョンでは型修飾子が適用されていませんでしたが、PostgreSQL 9.0では、これがplpgsql用に変更されました

PL / pgSQLでは、ベースタイプだけでなく期待されるタイプ修飾子と一致する複合結果の列が必要になりました(Pavel Stehule、Tom Lane)

たとえば、結果タイプの列がNUMERIC(30,2)として宣言されている場合、その列に他の精度のNUMERICを返すことはできなくなります。以前のバージョンでは、型修飾子のチェックが無視されていたため、宣言された制限に実際に準拠していない結果行が許可されていました。

問題を解決するための2つの基本的な方法:

  • 戻り値をキャストして、次の定義に一致させることができますpatient_for_registrar

    nfa.patient_id_number::varchar(8)
    
  • RETURNSまたは、句を変更できます。RETURNS TABLE一致する複合型を使用して宣言します。これがです。

    RETURNS TABLE (patient_for_registrar varchar, col2 some_type, ...)
    

余談ですが、回避できる場合は使用しませvarcharん。特に長さ修飾子を使用しない場合は使用しません。タイプができないことはほとんど何も提供しtextません。長さの制限が必要な場合は、テーブル全体を書き直さなくても変更できる列制約を使用します。

于 2012-05-25T17:23:23.137 に答える