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

89 postgresql variables

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

DECLARE @List AS VARCHAR(8)

SELECT @List = 'foobar'

SELECT *
FROM   dbo.PubLists
WHERE  Name = @List
Run Code Online (Sandbox Code Playgroud)

如何在PostgreSQL中完成?可以吗?

nad*_*000 123

完整的答案位于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 $$;
Run Code Online (Sandbox Code Playgroud)

您还可以获取最后一个插入 ID:

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

  SELECT * FROM test WHERE id = lastid;
END $$;
Run Code Online (Sandbox Code Playgroud)

  • 此示例中的代码不起作用.`错误:查询没有结果数据的目的地提示:如果要丢弃SELECT的结果,请改用PERFORM.语境:PL/pgSQL函数inline_code_block第7行在SQL语句` (39认同)
  • (并且不要忘记`END`之后的```,就像这样:`END $$;`.) (7认同)
  • 不适用于我的错误.我在开始和结束之间使用plpgsql语言也有一些功能. (3认同)
  • 作为 PostgreSQL 的新手,这让我困惑了一段时间,这里还有一些提示: + 确保以分号结束语句!+ 因为没有变量标识符,您可能需要使用 _ 或类似的东西来避免不明确的列名。+ 您可以使用这样的 DECLARE _accountid INT := 1; 将变量设置为行中的值 (3认同)
  • 别为我工作。使用松鼠。错误:错误:“$$ 处或附近未终止的美元引号字符串 (2认同)

小智 32

DO $$
DECLARE  
   a integer := 10;  
   b integer := 20;  
   c integer;  
BEGIN  
   c := a + b;
    RAISE NOTICE'Value of c: %', c;
END $$;
Run Code Online (Sandbox Code Playgroud)

  • 不要为我工作。使用松鼠。错误:ERROR:“ $$”或附近的不加引号的美元报价字符串 (2认同)
  • @VSO 与 SQL Server 和 MySQL 不同,PostgreSQL 不支持代码块之外的变量。通常这意味着一个功能块。“DO”块创建一个匿名块来为上述内容创建足够的编程环境。请参阅 https://www.postgresql.org/docs/current/sql-do.html (2认同)

小智 25

您可以使用:

\set list '''foobar'''
SELECT * FROM dbo.PubLists WHERE name = :list;
Run Code Online (Sandbox Code Playgroud)

那样做

  • @scw这只能从`psql`控制台获得.您将无法在应用程序的SQL中编写此代码. (10认同)
  • 这根本不回答这个问题.在MS SQL中,您可以在查询中定义var并在同一工具中使用它.我不明白为什么人们会在这个问题的每一个版本中继续提出这个答案. (4认同)
  • 错误:"\"或附近的语法错误我错过了什么? (2认同)
  • @stone显然是因为这是`postgresql`中的一个巨大的“失误”,并且它是最不糟糕的选择。总的来说,我对“postgresql”非常满意:但这是一个令人惊讶的巨大失败 (2认同)

ove*_*ink 9

这是在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
Run Code Online (Sandbox Code Playgroud)

有关更多信息,请查看plpgsql文档.


Jas*_*sen 7

Postgresql 没有裸变量,您可以使用临时表。变量仅在代码块中或作为用户界面功能可用。

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

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

SELECT dbo.PubLists.*
FROM   dbo.PubLists,list
WHERE  Name = list.column1;
Run Code Online (Sandbox Code Playgroud)


小智 5

我遇到了一些其他文档,它们\set用来声明脚本变量,但该值似乎类似于常量值,我正在寻找可以充当变量而不是常量变量的方法。

前任:

\set Comm 150

select sal, sal+:Comm from emp
Run Code Online (Sandbox Code Playgroud)

sal是表 'emp' 中comm存在的值并且是常量值。


Sha*_*ane 5

基于 @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 $$;
Run Code Online (Sandbox Code Playgroud)


Dav*_*eon 5

例如,在 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;
Run Code Online (Sandbox Code Playgroud)