0

SELECT次のようなステートメントで参照できる関数を介して結果セットを返す、シンプルで保守しやすい方法を見つけようとしています。

SELECT u.UserId, u.UserName, up.ProfileName
FROM GetUser(1) u
INNER JOIN user_profile up ON u.user_id = up.user_id; 

これが私がPostgresに持っているものです:

CREATE OR REPLACE FUNCTION GetUser(
  pUserId INTEGER
)
RETURNS TABLE (UserId INTEGER, UserClass CHAR(2), UserName VARCHAR(100)) AS $$
BEGIN
  RETURN QUERY
  SELECT UserId, UserClass, UserName
  FROM Users 
  WHERE (UserId = pUserId OR pUserId IS NULL)
  ;
END;
$$ LANGUAGE 'plpgsql';

SELECT * FROM GetUser(1);

以下は、私が Oracle で到達した場所の例です。

CREATE OR REPLACE TYPE appuser AS OBJECT (UserName VARCHAR(255)); -- user type
CREATE OR REPLACE TYPE appuser_table AS TABLE OF appuser; -- user table type

CREATE OR REPLACE FUNCTION GetUser (
  pUserId IN VARCHAR2 DEFAULT NULL
) RETURN appuser_table PIPELINED AS
BEGIN
  FOR v_Rec IN (
    SELECT UserName
    FROM Users
    WHERE (UserId = pUserId OR pUserId IS NULL)
  ) 
  LOOP
    PIPE ROW (appuser(v_Rec.UserName));
  END LOOP;

  RETURN;
END;

SELECT * FROM TABLE(GetUser(NULL));

動作しますが、扱いにくく、複数の DDL が必要です。Postgres では、関数内でこれらすべてを簡単に実行できます。

RETURNS TABLE (ObjectId INTEGER, ObjectClass CHAR(2), ObjectName VARCHAR(100))

Oracleでこれを行うためのよりクリーンな方法はありますか?

関連記事
関数 / SP での SELECT
DBMS_SQL.return_result
パイプライン関数

4

2 に答える 2

1

定義されたテーブル型 (SQL 型として、または PL/SQL パッケージ内のいずれか) を持つパイプライン化された関数は、19.6 までこれを実現する唯一の方法でした。このバージョンを使用すると、 SQL マクロを使用できます。特定の要件については、次のような単純な置換を行うことができます。

create or replace function getUser (pUserId  integer) 
return varchar2 sql_macro 
is
begin
  return q'{SELECT UserId, UserClass, UserName
  FROM Users 
  WHERE (UserId = pUserId OR pUserId IS NULL)}';
end getUser;
/

または、オプティマイザーでクエリを 2 つの可能な形式 (すべてを返すか、pUserId値に一致する行だけを返す) に分割することを容易にすることができます。

create or replace function getUser (pUserId  integer) 
return varchar2 sql_macro 
is
begin
  if pUserId is null then 
    return q'{SELECT UserId, UserClass, UserName FROM Users}';
  else 
    return q'{SELECT UserId, UserClass, UserName FROM  Users WHERE UserId = pUserId}';
  end if;
end getUser;
/

LiveSQLのデモをまとめました。

于 2020-11-22T19:53:55.343 に答える