如何在一个简单的 PostgreSQL 脚本中使用变量?

例如,在 MS-SQL 中,您可以打开一个查询窗口并运行以下命令:

DECLARE @List AS VARCHAR(8)


SELECT @List = 'foobar'


SELECT *
FROM   dbo.PubLists
WHERE  Name = @List

如何在 PostgreSQL 中实现这一点? 可以实现吗?

356271 次浏览

下面是在 plpgsql 中使用变量的一个示例:

create table test (id int);
insert into test values (1);
insert into test values (2);
insert into test values (3);


create function test_fn() returns int as $$
declare val int := 2;
begin
return (SELECT id FROM test WHERE id = val);
end;
$$ LANGUAGE plpgsql;


SELECT * FROM test_fn();
test_fn
---------
2

看一下 文件了解更多信息。

我遇到了一些其他的文档,他们使用 \set来声明脚本变量,但是这个值似乎是常量值,我正在寻找一种方法,它可以像变量一样,而不是常量变量。

例如:

\set Comm 150


select sal, sal+:Comm from emp

这里的 sal是表‘ em p’中的值,而 comm是常量值。

完整的答案在 PostgreSQL 官方文档中。

您可以使用新的 PG9.0匿名代码块特性(http://www.postgresql.org/docs/9.1/static/sql-do.html)

DO $$
DECLARE v_List TEXT;
BEGIN
v_List := 'foobar' ;
SELECT *
FROM   dbo.PubLists
WHERE  Name = v_List;
-- ...
END $$;

你也可以得到最后一个 插入 ID:

DO $$
DECLARE lastid bigint;
BEGIN
INSERT INTO test (name) VALUES ('Test Name')
RETURNING id INTO lastid;


SELECT * FROM test WHERE id = lastid;
END $$;

你可使用:

\set list '''foobar'''
SELECT * FROM dbo.PubLists WHERE name = :list;

可以了

DO $$
DECLARE
a integer := 10;
b integer := 20;
c integer;
BEGIN
c := a + b;
RAISE NOTICE'Value of c: %', c;
END $$;

我不得不这么做

CREATE OR REPLACE FUNCTION MYFUNC()
RETURNS VOID AS $$
DO
$do$
BEGIN
DECLARE
myvar int;
...
END
$do$
$$ LANGUAGE SQL;

Postgreql 没有裸变量,您可以使用一个临时表。 变量只能在代码块或用户界面特性中使用。

如果你需要一个纯变量,你可以使用一个临时表:

CREATE TEMP TABLE list AS VALUES ('foobar');


SELECT dbo.PubLists.*
FROM   dbo.PubLists,list
WHERE  Name = list.column1;

基于@nad2000的答案和 @ Pavel 的回答,这就是我最终得到 Flyway 迁移脚本的地方。处理手动修改数据库架构的方案。

DO $$
BEGIN
IF NOT EXISTS(
SELECT TRUE FROM pg_attribute
WHERE attrelid = (
SELECT c.oid
FROM pg_class c
JOIN pg_namespace n ON n.oid = c.relnamespace
WHERE
n.nspname = CURRENT_SCHEMA()
AND c.relname = 'device_ip_lookups'
)
AND attname = 'active_date'
AND NOT attisdropped
AND attnum > 0
)
THEN
RAISE NOTICE 'ADDING COLUMN';
ALTER TABLE device_ip_lookups
ADD COLUMN active_date TIMESTAMP;
ELSE
RAISE NOTICE 'SKIPPING, COLUMN ALREADY EXISTS';
END IF;
END $$;

例如,在 alter table 中使用变量:

DO $$
DECLARE name_pk VARCHAR(200);
BEGIN
select constraint_name
from information_schema.table_constraints
where table_schema = 'schema_name'
and table_name = 'table_name'
and constraint_type = 'PRIMARY KEY' INTO name_pk;
IF (name_pk := '') THEN
EXECUTE 'ALTER TABLE schema_name.table_name DROP CONSTRAINT ' || name_pk;

您还可以简单地创建在实际查询中使用的常量查询:

WITH vars as (SELECT list 'foobar')
SELECT *
FROM   dbo.PubLists, vars
WHERE  Name = vars.list

任何无意中发现这个帖子的人-这些在 postgres 中的声明和函数都是狗屎。只需使用 with 语句并在查询中选择该表/列:


with merchant_id_var as (
select
12345 as merchant_id
)
    

select *
from merchants
where merchant_id = (select merchant_id from merchant_id_var)