尝试从命令行保存并执行psql函数脚本

时间:2016-08-26 14:24:06

标签: postgresql

我创建了一个函数并将其保存在.sql文件中。我想使用此文件和函数将文件放在系统上,然后通过命令行执行包含的函数,以便将新数据保存到该系统上的数据库中。

目前,我的.sql文件的内容是:

search_path

当我尝试使用该命令运行文件时,我使用了以下命令

CREATE OR REPLACE
FUNCTION device_authorisation_change(device_identification VARCHAR)
 RETURNS VARCHAR AS
$$
DECLARE 
  OWNER varchar(255);
  DEVICE_ID integer;
  OWNER_ID integer;
  DATE_TIME timestamp;

BEGIN
  OWNER := 'MyDefaultOrganisation';
  DATE_TIME := current_timestamp;

  DEVICE_ID := (SELECT id from device dev where dev.device_identification = $1);
  OWNER_ID := (SELECT id from owners own where own.owner_identification = OWNER);

  DELETE FROM device_authorization
  WHERE device = DEVICE_ID AND owner = OWNER_ID;

  INSERT INTO device_authorization(id, creation_time, device, owner)
  VALUES (nextval('device_authorization_id_seq'), DATE_TIME, DEVICE_ID, OWNER_ID);

  RAISE NOTICE 'Deleted device authorisations for % for device: %' , OWNER,  $1;

  RETURN '';
END;
$$ LANGUAGE plpgsql;

,结果显示de device_identification似乎是psql -d my_database -f ChangeOwnership.sql -v device_identification='TestDevice' 。但是,该函数存储到数据库中,我可以使用

执行此函数(在pgAdmin中)
NULL

这次,该功能执行得很好。

我想要实现的是我可以从命令行运行sql脚本,使用(命名)参数,它立即更新数据库中的数据。没有必要将函数保存在数据库中,我实际上想要避免使用它,但是如果它使事情变得复杂,那么如果它保留在数据库中则不是问题。

任何人都可以帮助我吗?

2 个答案:

答案 0 :(得分:1)

您的函数没有被调用,因为您没有在SQL脚本中包含SELECT语句。那里只有一个声明(CREATE FUNCTION),并且正式执行。如果您想在之后删除该函数,那么您还需要在SQL脚本中使用DROP FUNCTION语句。

但由于您的功能没有返回任何有意义的内容,我建议您改用DO statement。这样您就可以执行PL / pgSQL代码而无需定义函数。

答案 1 :(得分:1)

如果你想避免在数据库中创建函数,实际上使用psql的变量而不是PL / pgSQL代码更容易:

i

然后你可以保存它并按照你之前的尝试运行:

\set owner 'MyDefaultOrganisation'
\set ON_ERROR_STOP 1
-- Let's open a transaction, so we do all or nothing
BEGIN;
  -- Execute the query and set variables with the output using \gset
  SELECT id AS device_id
  FROM device dev
  WHERE dev.device_identification = :'device_identification' \gset

  SELECT id AS owner_id
  FROM owners own
  WHERE own.owner_identification = :'owner' \gset

  DELETE FROM device_authorization
  WHERE device = :'device_id' AND owner = :'owner_id';

  INSERT INTO device_authorization(id, creation_time, device, owner)
  VALUES (nextval('device_authorization_id_seq'), current_timestamp, :'device_id', :'owner_id');
COMMIT;

您甚至可以使用CTEs (Common Table Expression)将其全部重写为单个语句:

psql -d my_database -f ChangeOwnership.sql -v device_identification='TestDevice'