在 DO 块内使用 psql 元命令设置的变量

2024-05-26

这是我想做的:

\set values foo,bar,baz

DO $$
DECLARE
    value  TEXT;
    values TEXT[] := string_to_array(:'values', ',');
BEGIN
    FOREACH value IN ARRAY values LOOP
        raise notice 'v: %', value;
    END LOOP;
END $$ LANGUAGE plpgsql;

这会导致以下错误:

ERROR:  syntax error at or near ":"
SELECT string_to_array(:'values', ',') INTO values...
                       ^

这是我目前的解决方案,但感觉很hacky:

\set values foo,bar,baz

PREPARE get_values AS SELECT string_to_array(:'values', ',');

DO $$
DECLARE
    value  TEXT;
    values TEXT[];
BEGIN
    EXECUTE 'EXECUTE get_values' INTO values;

    FOREACH value IN ARRAY values LOOP
        raise notice 'v: %', value;
    END LOOP;
END $$ LANGUAGE plpgsql;

Answer

DO http://www.postgresql.org/docs/current/interactive/sql-do.html期望一个字符串字面量与 plpgsql 代码。 psql 中的字符串内部不会替换符号。
您可以将整个字符串连接到 psql 变量中,然后then执行它。

  • 如何连接psql变量? https://dba.stackexchange.com/a/21131/3684

漂亮的多行格式是不可能的,因为(根据文档 http://www.postgresql.org/docs/current/interactive/app-psql.html#APP-PSQL-META-COMMANDS):

但无论如何,元命令的参数不能继续下去 超出该线的末端。

简单的例子:

test=# \set value foo
test=# \set do 'BEGIN\n   RAISE NOTICE ''v: %'', ' :'value' ';\nEND'
test=# DO :'do';
NOTICE:  v: foo

将换行符替换为\n(或者如果您不喜欢漂亮的格式,请将它们删除)。基于此改编代码:

DO
'
DECLARE
   _val  text;
   _vals text[] := string_to_array(>>values<<, '','');
BEGIN
   FOREACH _val IN ARRAY _vals
   LOOP
     RAISE NOTICE ''v: %'', _val;
   END LOOP;
END
'

它看起来像这样:

test=# \set do 'DECLARE\n   _val  text;\n   _vals text[] := string_to_array(' :'values' ', '','');\nBEGIN\n   FOREACH _val IN ARRAY _vals\n   LOOP\n     RAISE NOTICE ''v: %'', _val;\n   END LOOP;\nEND'
test=# DO :'do';
NOTICE:  v: foo
NOTICE:  v: bar
NOTICE:  v: baz
DO

I added bold强调变量,以便更容易发现。

@Pavel (ab)使用的相关答案服务器会话变量 http://www.postgresql.org/docs/current/interactive/runtime-config-custom.html:

  • 从 PL/PGSQL 引用会话变量 (\set var='value') https://stackoverflow.com/questions/28868514/referring-to-session-variables-set-var-value-from-pl-pgsql/28871424#28871424

替代解决方案

准备好的声明

您当前的解决方案看起来并没有那么糟糕。我会简化:

PREPARE get_values AS SELECT * FROM regexp_split_to_table(:'values', ',');

DO
$do$
DECLARE
   _val text;
BEGIN
   FOR _val IN EXECUTE
      'EXECUTE get_values'
   LOOP
      RAISE NOTICE 'v: %', _val;
   END LOOP;
END
$do$;

临时表

使用临时表的类似解决方案:

CREATE TEMP TABLE tmp AS SELECT * FROM regexp_split_to_table(:'values', ',') v;

DO
$do$
DECLARE
   _val text;
BEGIN
   FOR _val IN
      TABLE tmp
   LOOP
      RAISE NOTICE 'v: %', _val;
   END LOOP;
END
$do$;
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 DO 块内使用 psql 元命令设置的变量 的相关文章

随机推荐

  • 正则表达式查找两个字符之间的内部匹配

    环境 Java 我想匹配两个字符串之间的字符 这是一个例子 foo
  • 如何从 Perl 中的文本文件中提取/解析表格数据?

    我正在寻找类似的东西HTML 表格提取 http search cpan org dist HTML TableExtract 只是不适用于 HTML 输入 而是适用于包含采用缩进和间距格式化的 表格 的纯文本输入 数据可能如下所示 Her
  • Android 上下文不在活动中?还有其他无活动编程吗?

    我会非常努力地将其变成一个综合问题 我正在编写一个方法来获取一个包含 Android 设备城市名称的字符串 该名称由LocationManager and getLastKnownLocation 等等 然后我意识到我需要在另一个活动中再次
  • Gradle中的build-by-convention深度解释是什么?

    The 摇篮用户指南 http www gradle org docs current userguide userguide html经常提到 Gradle 是陈述性的和用途按惯例构建 这是什么意思 据我了解 这意味着 例如 在java插
  • 清理 php 中的句子

    标题可能听起来很奇怪 但我有点尝试设置这个 preg replace 来处理文本区域的混乱写入者 它必须 如果有感叹号 则不应连续出现另一个感叹号 如果有 则逗号胜出 并且必须是 当昏迷前有一个 空格时 应将其减少到零 该句子不能以逗号开头
  • 移动相邻选项卡以进行拆分?

    有没有一种简单的方法可以将 Vim 中的相邻选项卡作为拆分移动到当前窗口 While looking around I reached a mailing list discussion where someone said it s th
  • C++ 中的前向声明是什么?

    At this http www learncpp com cpp tutorial 19 header files 链接 提到了以下内容 add cpp int add int x int y return x y 主要 cpp incl
  • Swift 中的 titleLabel.text 与 currentTitle

    我正在尝试用 Swift 制作一个简单的计算器 我想获取我创建的按钮上的 文本 本教程中的讲师正在使用一个属性 IBAction func appendDigit sender UIButton let digit sender curre
  • Ruby on Rails:如何检查复数形式和单一形式的名称

    我用命令创建了一个匿名模型 rails g model Anonymous section id integer aid string fake bool active bool 但迁移中的表名称为匿名 class CreateAnonym
  • 如何使用 PowerShell 捕获全局击键?

    Powershell 可以监听并捕获按键吗 是否可以编写一个 PowerShell 脚本 例如自动热键 https www autohotkey com 位于托盘中并等待您按下预定义的键盘键才开始执行 并且每次按下所述键时可能不会返回而是触
  • 在 Spring Security 中创建自定义 PostAuthorize 方法

    我正在尝试创建一个自定义方法 用于预 后授权调用 如下所示 public class CustomLSecurityExpressionHandler extends DefaultMethodSecurityExpressionHandl
  • 如何使用社交框架呈现 SKscene 中的 UIViewController?

    我正在制作一款类似 Flappy Bird 的游戏 如何从 SKScene 呈现 UIViewController 首先 我告诉我的环境 Mac OS X 10 9 Xcode 5 0 2 Sprite Kit framework soci
  • 如何用c语言运行可执行文件?

    我试图使用 C 语言编译器 3 0 执行这个程序 一切正常 但是当我运行这个程序时 它永远不会打开 Firefox 当我运行这个程序的可执行文件时 它显示兼容性问题错误 请帮助我 include
  • 填充占位符文本 ios

    我想让占位符文本显示在文本字段的中间 填充占位符文本 占位符文本的大小也需要增加 我的代码如下 我该如何解决这个问题 UITextField textField UITextField alloc initWithFrame CGRectM
  • 内联函数与预处理器宏

    内联函数与预处理器宏有何不同 预处理器宏只是应用于代码的替换模式 它们几乎可以在代码中的任何地方使用 因为在任何编译开始之前它们都会被替换为扩展 内联函数是实际函数 其主体直接注入到其调用站点中 它们只能在适合函数调用的地方使用 现在 就在
  • DrawBitmapMesh 如何在 Android Canvas 中工作

    我想在矩形上绘制位图 我使用以下值 this meshWidth 1 this meshHeight 1 this verts new float 8 this points 0 x float this getWidth 4 this p
  • 正则表达式删除带有数字的单词

    我想删除产品名称中带有数字 参考 或小单词 2 个或更少字符 的单词 但我找不到好的正则表达式 一些例子 链式防回弹ECS 2035 应成为 链式防反弹 指南 35 厘米俄勒冈 Intenz 应该成为 俄勒冈州 Intenz 指南 Tron
  • git apply 不对文件进行任何更改

    我必须对我的存储库应用补丁并正在运行 git apply directory PWD xxxxx patch 由于我不会详细讨论的原因 我无法使用git am在这种情况下 我需要使用目录标志 吉特告诉我 gt git apply direc
  • TypeError:无法在 re.findall() 中的类似字节的对象上使用字符串模式

    我正在尝试学习如何自动从页面获取网址 在下面的代码中 我试图获取网页的标题 import urllib request import re url http www google com regex r pattern re compile
  • 在 DO 块内使用 psql 元命令设置的变量

    这是我想做的 set values foo bar baz DO DECLARE value TEXT values TEXT string to array values BEGIN FOREACH value IN ARRAY valu