返回依赖于情境的消息(例外)

时间:2014-11-10 14:06:10

标签: postgresql stored-procedures unique plpgsql

我的PostgreSQL环境中有存储过程。其中一个过程存储用户定义的数据。

在plpgsql语言中,我想实现以下处理:

因为目标表中存在唯一约束,所以我首先检查受影响的属性是否已在此表中。如果是这样,我希望存储过程返回这些受影响的属性,因此用户知道:"呃,我的一些数据已经存在,让我们尝试不同的东西!"

例如受影响的表格的一部分:

CREATE TABLE XYZ (
  Name varchar UNIQUE
  ...
)

现在我想向XYZ添加一个新行。如果该函数注意到该名称已存在,则应返回带有违规name的消息。可以有多个重复项,该函数应该返回所有这些重复项。如何实施?

我首先想过单独检查每个属性,但这很慢:

-- Check, if abbreviation or name already exist.
SELECT EXISTS(
  SELECT
    1
  FROM
    "sample-scheme"."sample-table" AS tableName
  WHERE
    tableName.abbreviation = argAbbreviation
  OR
    tableName.name = argName
)
INTO
  varEntryExists;

-- If abbreviation or name exists, return error message.
IF varEntryExists THEN
  RETURN "Already exists.";
END IF;

此示例也不会返回违规属性。

1 个答案:

答案 0 :(得分:0)

您只需要这个简单的查询:

SELECT name
FROM   XYZ
JOIN   unnest ('{name1, name2, name3}'::varchar[]) AS n(name) USING (name);

或者使用"is contained by" operator <@(对于小数组更快):

SELECT name
FROM   XYZ
WHERE  name <@ '{name1, name2, name3}'::varchar[]

包装到函数中,要返回多个查找,您可以返回一个数组,或者RETURNS SETOF ...RETURNS TABLE(...)返回一个集合。使用方便的VARIADIC参数演示plpgsql函数(也可能只是SQL):

CREATE OR REPLACE FUNCTION f_name_dupes(VARIADIC _names varchar[])
  RETURNS SETOF varchar AS
$func$
BEGIN
   SELECT name
   FROM   XYZ x
   WHERE  name <@ $1;
END
$func$  LANGUAGE sql;

呼叫:

SELECT * FROM f_name_dupes('name1', 'name2', 'name3');

返回表XYZ中已存在的所有名称。有关VARIADIC的详细信息: