标签: plpgsql

使用动态 SQL 重置串行 PK 的顺序

如何使用字符串和DECLARE变量的组合动态引用序列名称(如下所示)?下面的代码是否正确或者是否有其他方法可以做到这一点?

DO我的目标是出于性能原因在/块中执行此操作BEGIN,而且它将通过做一些有用的事情来帮助我理解 plpgsql,因此除非确实必须,否则我不会将其混合到 PHP 中。

DO $$
 DECLARE PKEY VARCHAR;
BEGIN

SELECT pg_attribute.attname INTO PKEY 
FROM pg_index, pg_class, pg_attribute 
WHERE pg_class.oid = 'parts1'::regclass 
AND indrelid = pg_class.oid 
AND pg_attribute.attrelid = pg_class.oid 
AND pg_attribute.attnum = any(pg_index.indkey) 
AND indisprimary;

--SELECT setval('parts1_id_seq', (SELECT MAX(pkey) + 1 FROM parts));
SELECT setval('parts1_' || PKEY || '_seq', (SELECT MAX(pkey) + 1 FROM parts));

  END;
$$ LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)

postgresql auto-increment dynamic-sql plpgsql

3
推荐指数
1
解决办法
1888
查看次数

使用动态 SQL 函数中的参数进行通配符搜索

在使用动态 SQL 的函数中使用参数时,在 PostgreSQL 中实现通配符搜索的正确方法是什么?

作为起点,以下是 Erwin Brandstetter 在 stackoverflow 上回答不同问题的示例:

/sf/answers/843309421/

CREATE OR REPLACE FUNCTION report_get_countries_new (starts_with text
                                                   , ends_with   text = NULL)
RETURNS SETOF lookups.countries AS
$func$
DECLARE
   sql text := 'SELECT * FROM lookups.countries WHERE country_name >= $1';
BEGIN
   IF ends_with IS NOT NULL THEN
      sql := sql || ' AND country_name <= $2';
   END IF;

   RETURN QUERY EXECUTE sql
   USING starts_with, ends_with;
END
$func$ LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)

假设country_name您想要进行前导和尾随通配符搜索。

例如,不使用参数,AND country_name LIKE '%ic%'.

在这种情况下,在否定 …

postgresql sql-injection dynamic-sql plpgsql

3
推荐指数
1
解决办法
9182
查看次数

错误:“sql”不是已知变量

这一定是我在这里问过的最愚蠢的问题之一,但是我的 SQL 脚本中肯定隐藏着一些非常恶心的问题,阻止它运行。

我正在使用以下示例 CLI 语法调用 cobertura.sql 文件:

psql -h localhost -U myUser -f cobertura.sql myDB
Run Code Online (Sandbox Code Playgroud)

但它抱怨以下错误:

psql:cobertura.sql:29: ERROR:  "sql " is not a known variable
LINE 14: sql := format('insert into cobertura_tmp select count(*) as ... cobertura.sql file:
Run Code Online (Sandbox Code Playgroud)
DO language plpgsql $$
declare 
    eq  record;
    sql varchar;
BEGIN

create table if not exists cobertura_tmp  (num integer, realtime char(1), lat numeric, lng numeric);

truncate table cobertura_tmp;
for eq in select imei_equipo as imei  from cliente_avl_equipo where id_cliente in (select id …
Run Code Online (Sandbox Code Playgroud)

postgresql scripting plpgsql postgresql-9.4 unicode

3
推荐指数
1
解决办法
4757
查看次数

Postgres 将表声明为函数的参数?

我想创建一个对表进行操作的函数,例如

create or replace function test(t table) 
    returns void language plpgsql as
$func$
begin   
    select * from t limit 10;
end;
$func$
Run Code Online (Sandbox Code Playgroud)

然后,我可以使用任何表名调用该函数,例如

select test(myTable);
Run Code Online (Sandbox Code Playgroud)

我该怎么做这样的事情?

postgresql plpgsql

3
推荐指数
1
解决办法
2万
查看次数

处理 PARTITION BY RANGE 上超出范围的值

我有一个用于存储事件的表,该表timestamptz使用按月按列分区PARTITION BY RANGE

目前有 5 个分区,每个分区包含一个月的跨度,从 开始FOR VALUES FROM ('2018-01-01') TO ('2018-02-01')到结束FOR VALUES FROM ('2018-05-01') TO ('2018-06-01')

大多数数据都是以线性且可预测的方式输入的。但是,事件由报告事件的应用程序消耗,并且我确实必须允许随时输入过去的事件 - 其时间戳可能早于2018-01-01,甚至是未来的事件(例如预计的费用)发生在未来的某个时间)。

我计划为过去的事件创建一个分区,这些事件的跨度将超过一个月,因为预计不会有太多此类事件。

我不确定对于尚未存在分区的未来事件的最佳方法是什么。

有没有办法获取我可以在现有分区中存储的最小/最大值?如果没有,我可以创建一个参考表来存储这些值,但我宁愿不必维护它。

我应该创建一个触发器来检查插入的每一行(看起来很昂贵)吗?我应该捕获插入错误并一次处理这些错误吗?

运行于PostgreSQL 10.3.

postgresql partitioning plpgsql postgresql-10

3
推荐指数
1
解决办法
1894
查看次数

POSTGRES 在函数中声明包含日期数组的变量

我正在尝试声明一个日期数组。

我试过这个:

DECLARE
dateVal DATE[] := ['2018-01-01','2018-02-01'];
Run Code Online (Sandbox Code Playgroud)

我得到:

ERROR:  syntax error at or near "["
Run Code Online (Sandbox Code Playgroud)

我如何正确声明它?

postgresql plpgsql array

3
推荐指数
2
解决办法
3万
查看次数

如何在过程(不是函数)中使用变量?

据我了解,在 Postgres 中,过程用于操作数据,函数用于读取数据。我想要:

  1. 声明一个变量
  2. 选择一个值到一个变量中
  3. 将变量插入另一个表
  4. 在事务中执行此操作
  5. 在存储过程中执行此操作
  6. 必要时回滚

CREATE PROCEDURE test_variable()
LANGUAGE SQL
AS $$
    BEGIN;
        DECLARE some_id INTEGER;
        SELECT nextval('some_sequence') INTO some_id;
        INSERT INTO some_table (some_column) VALUES (some_id);
    END;
$$;
Run Code Online (Sandbox Code Playgroud)

以上对我不起作用。当我寻找解决方案时,有很多不同的变量涉及函数$$、声明、事物不返回任何内容;似乎找不到一个简单的例子;我只需要一个清晰的语法示例。

postgresql transaction plpgsql functions sql-procedure

3
推荐指数
1
解决办法
9629
查看次数

无法在 PostgreSQL 11.5 中创建 COMMIT 过程

我正在尝试学习 PostgreSQL 存储过程。具体在 PSQL 中创建以下过程。

CREATE OR REPLACE PROCEDURE BUILD_AND_POPULATE(INOUT cresults refcursor) 
    LANGUAGE PLPGSQL 
    AS $$
    BEGIN
        BEGIN; -- I've tried removing this but the behaviour is the same
        cresults:= 'cur';
        DROP TABLE IF EXISTS procsampledata;
        CREATE TABLE procsampledata as select x,1 as c2,2 as c3, md5(random()::text) from generate_series(1,10) x;  
        COMMIT;
        OPEN cresults FOR SELECT * FROM procsampledata;  
    END;
$$;
Run Code Online (Sandbox Code Playgroud)

然后我像这样执行它,但收到一个错误:

postgres=# call build_and_populate(null);
ERROR:  invalid transaction termination
CONTEXT:  PL/pgSQL function build_and_populate(refcursor) line 6 at COMMIT
Run Code Online (Sandbox Code Playgroud)

我试过将 AUTOCOMMIT 设置为打开和关闭。

这是我的 …

postgresql plpgsql

3
推荐指数
1
解决办法
7492
查看次数

PLPGSQL 捕获循环中的任何异常

我有以下地理编码功能,无需该EXCEPTION WHEN OTHERS THEN部分即可正常工作。但是,我希望循环继续,以防出现异常。所以我试图通过使用来做到这一点EXCEPTION WHEN OTHERS THEN

CREATE OR REPLACE FUNCTION mygetcounty2() RETURNS void LANGUAGE PLPGSQL AS $$
DECLARE idVariable uuid;
begin
FOR i IN 1..100 LOOP

SELECT id into idVariable FROM address_table WHERE county IS NULL AND parse_address_error = false LIMIT 1;

UPDATE address_table set county =
(select namelsad from tiger_data.county_all where ST_Contains( the_geom, ST_GeomFromText( (SELECT ST_AsText( ST_SnapToGrid(g.geomout, 0.00001) ) As wktlonlat FROM geocode(address, 1 ) AS g), 4269 ) ))
where id = idVariable;
EXCEPTION …
Run Code Online (Sandbox Code Playgroud)

postgresql plpgsql

3
推荐指数
1
解决办法
3723
查看次数

Postgres 中 FORMAT() 函数内的转义 %

我正在尝试转义 PostgreSQL 中 format() 函数内的“%”字符。\n该函数根据列列表替换列值,删除返回值 (\\n) 并修剪字符串。

\n
CREATE OR REPLACE FUNCTION eliminar_retornos(text) RETURNS VOID\nAS $$\n        declare\n            i text;\n            fields text[] := ARRAY['direccion', 'localidad', 'calle', 'esq1', 'esq2', 'obs'];\n        BEGIN\n            FOREACH i IN ARRAY fields\n            loop\n                EXECUTE format(\n                    'update %1$s set %2$s = trim(upper(replace(%2$s, E''\\n'', '' '')))', $1, i)\n                ;\n            END LOOP;\n        RAISE NOTICE 'Se actualiz\xc3\xb3 la capa %', $1;\n        END\n        ;\n$$ LANGUAGE plpgsql;\n\n
Run Code Online (Sandbox Code Playgroud)\n

我想更改此函数以仅替换那些有返回的字符串,使用类似的东西;

\n
'update %1$s set %2$s = trim(upper(replace(%2$s, E''\\n'', '' ''))) where %2$s LIKE E''%\\n%''', $1, …
Run Code Online (Sandbox Code Playgroud)

postgresql plpgsql

3
推荐指数
1
解决办法
3197
查看次数