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

Postgresql 试图从命令行保存并执行psql函数脚本,postgresql,Postgresql,我创建了一个函数并将其保存在.sql文件中。我想使用这个文件和函数将文件放在一个系统上,然后通过命令行执行包含的函数,这样新数据就会保存到该系统上的数据库中 当前,my.sql文件的内容是: CREATE OR REPLACE FUNCTION device_authorisation_change(device_identification VARCHAR) RETURNS VARCHAR AS $$ DECLARE OWNER varchar(255); DEVICE_ID in

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

当前,my.sql文件的内容是:

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;
当我尝试使用命令运行该文件时,我使用了以下命令

psql -d my_database -f ChangeOwnership.sql -v device_identification='TestDevice' 
结果表明,de设备_标识似乎是
NULL
。但是,该函数被存储到数据库中,我可以使用

这一次,函数执行得很好

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


有人能帮我吗?

您的函数没有被调用,因为您没有在SQL脚本中包含
SELECT
语句。那里只有一条语句(
CREATE FUNCTION
)被正确执行。如果您想在以后删除该函数,还需要在SQL脚本中使用
DROP function
语句


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

您的函数不会被调用,因为您没有在SQL脚本中包含
SELECT
语句。那里只有一条语句(
CREATE FUNCTION
)被正确执行。如果您想在以后删除该函数,还需要在SQL脚本中使用
DROP function
语句


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

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

\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;
然后,您可以保存它并完全按照以前的方式运行:

psql -d my_database -f ChangeOwnership.sql -v device_identification='TestDevice'
您甚至可以使用以下语句将其全部重写为一条语句:


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

\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;
然后,您可以保存它并完全按照以前的方式运行:

psql -d my_database -f ChangeOwnership.sql -v device_identification='TestDevice'
您甚至可以使用以下语句将其全部重写为一条语句:


阅读关于在不需要创建函数的情况下执行匿名代码块的语句:)阅读关于在不需要创建函数的情况下执行匿名代码块的语句:)我无法运行该文件,因为参数\g集未知,但如果没有它,一切正常!谢谢你的帮助@Joetjah\gset有点新,因为PostgreSQL 9.3。第二个版本应该可以运行,因为9.1I无法运行该文件,因为参数\g集未知,但是没有它,一切都可以正常运行!谢谢你的帮助@Joetjah\gset有点新,因为PostgreSQL 9.3。第二个版本应该从9.1开始运行