Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在PostgreSQL中使用存储过程动态传递数据库和表名_Postgresql_Stored Procedures - Fatal编程技术网

在PostgreSQL中使用存储过程动态传递数据库和表名

在PostgreSQL中使用存储过程动态传递数据库和表名,postgresql,stored-procedures,Postgresql,Stored Procedures,我正在PostgreSQL中创建一个存储过程,它将首先根据'ID'检查给定表中是否存在数据。如果是,则将其移动到其他表中,并在给定表名中插入最新记录。我编写了一个存储过程,我尝试使用硬编码的值,它可以根据我的需要工作,但是当我尝试使它成为通用的,即创建变量,然后将这些变量传递到查询中时,它会抛出一个错误。我参考了下面的,因此链接了,并且能够修改我的存储过程: 下面是我的存储过程: CREATE OR REPLACE PROCEDURE compareDups(ab integer, b js

我正在
PostgreSQL
中创建一个存储过程,它将首先根据
'ID'
检查给定表中是否存在数据。如果是,则将其移动到其他表中,并在给定表名中插入最新记录。我编写了一个存储过程,我尝试使用硬编码的值,它可以根据我的需要工作,但是当我尝试使它成为通用的,即创建变量,然后将这些变量传递到查询中时,它会抛出一个错误。我参考了下面的
,因此链接了
,并且能够修改我的存储过程:

  • 下面是我的存储过程:

    CREATE OR REPLACE PROCEDURE compareDups(ab integer, b json, tablename varchar)
    AS $$
    DECLARE 
      actualTableName varchar := 'testing.'||tablename;
      histTableName varchar:= actualTableName ||'_hist';
      job_id Integer:=0;
    BEGIN --<<<< HERE
      EXECUTE 'SELECT id FROM '||actualTableName||' WHERE id =$1' INTO job_id USING ab;
      -- if there is data for id in the table then perform below operations
      IF job_id IS NOT NULL THEN
          EXECUTE FORMAT('INSERT INTO %I as select * from %L where id = $1',histTableName,actualTableName) USING ab;
          EXECUTE FORMAT('DELETE FROM %I where id = $1',actualTableName) USING ab;
          EXECUTE FORMAT('INSERT INTO %I values($1,$2)',actualTableName) USING ab,b;
      -- if id is not present then create a new record in the actualTable
      ELSE    
          EXECUTE FORMAT('INSERT INTO %I values($1,$2)',actualTableName) USING ab,b;
      END IF;
    
    END; --<<<< END HERE
    $$
    LANGUAGE plpgsql;
    

    我在这里遗漏了什么?

    所以,我想回答我自己的问题,也许它能帮助像我这样的人。我可以通过修改
    actualtablename
    字符串来修复上面的代码,我也在这里设置了
    schema name
    。因此,我在过程中添加了一个
    SET
    语句,用于在需要执行预期操作的地方设置模式名称,这对我来说很有效

    CREATE OR REPLACE PROCEDURE compareDups(ab integer, b json, tablename varchar)
    AS $$
    DECLARE 
      actualTableName varchar := tablename;
      histTableName varchar:= actualTableName ||'_hist';
      job_id Integer:=0;
    BEGIN --<<<< HERE
      SET search_path to testing; -- Set the schema name
      EXECUTE 'SELECT id FROM '||actualTableName||' WHERE id =$1' INTO job_id USING ab;
      -- if there is data for id in the table then perform below operations
      IF job_id IS NOT NULL THEN
          EXECUTE FORMAT('INSERT INTO %I select * from %I where id = $1',histTableName,actualTableName) USING ab;
          EXECUTE FORMAT('DELETE FROM %I where id = $1',actualTableName) USING ab;
          EXECUTE FORMAT('INSERT INTO %I values($1,$2)',actualTableName) USING ab,b;
      -- if id is not present then create a new record in the actualTable
      ELSE    
          EXECUTE FORMAT('INSERT INTO %I values($1,$2)',actualTableName) USING ab,b;
      END IF;
    
    END; --<<<< END HERE
    $$
    LANGUAGE plpgsql;  
    

    您缺少的是“testing.sampletesting_hist”应该是“testing”。“sampletesting_hist”也是无效的“testing.sampletesting”。标识符需要双引号。是的,我知道了:)您没有对
    过程
    名称进行模式限定,因此它是在
    搜索路径
    的第一个模式中创建的。在过程中设置搜索路径仅在过程内部有效。显式优于隐式如果您希望将对象指定给架构,则以这种方式命名,例如my_schema.compareDups。或者
    SET search\u path
    是否紧跟在
    CREATE
    之前?您的意思是我应该在创建过程之前指定SET search\u path命令,以便在该架构下创建?是的。虽然更好的选择是创建或替换过程测试。比较(…)
    ,那么就没有猜测了。是的,让我试试这个。谢谢@Adrian;)
    CREATE OR REPLACE PROCEDURE compareDups(ab integer, b json, tablename varchar)
    AS $$
    DECLARE 
      actualTableName varchar := tablename;
      histTableName varchar:= actualTableName ||'_hist';
      job_id Integer:=0;
    BEGIN --<<<< HERE
      SET search_path to testing; -- Set the schema name
      EXECUTE 'SELECT id FROM '||actualTableName||' WHERE id =$1' INTO job_id USING ab;
      -- if there is data for id in the table then perform below operations
      IF job_id IS NOT NULL THEN
          EXECUTE FORMAT('INSERT INTO %I select * from %I where id = $1',histTableName,actualTableName) USING ab;
          EXECUTE FORMAT('DELETE FROM %I where id = $1',actualTableName) USING ab;
          EXECUTE FORMAT('INSERT INTO %I values($1,$2)',actualTableName) USING ab,b;
      -- if id is not present then create a new record in the actualTable
      ELSE    
          EXECUTE FORMAT('INSERT INTO %I values($1,$2)',actualTableName) USING ab,b;
      END IF;
    
    END; --<<<< END HERE
    $$
    LANGUAGE plpgsql;  
    
    set search_path to public;
    call compareDups(12,'{"name":"CTTT"}','sampletesting');