CREATE FUNCTION var(name text, val text) RETURNS void AS $$
$_SHARED{$_[0]} = $_[1];
$$ LANGUAGE plperl;
CREATE FUNCTION var(name text) RETURNS text AS $$
return $_SHARED{$_[0]};
$$ LANGUAGE plperl;
表格版本:
CREATE TABLE var (
sess bigint NOT NULL,
key varchar NOT NULL,
val varchar,
CONSTRAINT var_pkey PRIMARY KEY (sess, key)
);
CREATE FUNCTION var(key varchar, val anyelement) RETURNS void AS $$
DELETE FROM var WHERE sess = pg_backend_pid() AND key = $1;
INSERT INTO var (sess, key, val) VALUES (sessid(), $1, $2::varchar);
$$ LANGUAGE 'sql';
CREATE FUNCTION var(varname varchar) RETURNS varchar AS $$
SELECT val FROM var WHERE sess = pg_backend_pid() AND key = $1;
$$ LANGUAGE 'sql';
13条答案
按热度按时间smdnsysy1#
专门为
psql
,你可以通过psql
来自命令行的变量;你可以把它们拿过来-v
. 下面是一个用法示例:请注意,冒号是不带引号的,那么变量名本身就是带引号的。奇怪的语法,我知道。这只适用于psql;它在pgadmin-iii中不起作用。
这种替换发生在psql的输入处理过程中,因此您不能(假设)定义一个使用
:'filepath'
并期望:'filepath'
从一节课改到另一节课。当函数被定义时,它将被替换一次,然后是一个常量。它对于脚本编写很有用,但对于运行时使用却不太有用。mlmc2os52#
另一种方法是(ab)使用postgresql guc机制来创建变量。有关详细信息和示例,请参阅前面的回答。
你宣布guc在
postgresql.conf
,然后在运行时使用SET
命令并获取其值current_setting(...)
.我不建议在一般情况下使用它,但它可能在一些狭窄的情况下很有用,比如在链接问题中提到的情况,发帖者想要一种方法来为触发器和函数提供应用程序级别的用户名。
wmtdaxz33#
postgres变量是通过\set命令创建的,例如。。。
... 然后可以被替代,例如。。。
... 或者。。。
编辑:从PSQL9.1开始,变量可以用引号展开,如下所示:
在旧版本的psql客户端中:
... 如果要将变量用作条件字符串查询中的值,例如。。。
... 然后您需要在变量本身中包含引号,因为上面的方法不起作用。相反,将变量定义为。。。
但是,如果你和我一样,遇到了一个想从现有变量生成字符串的情况,我发现其中的诀窍是。。。
现在您有了一个带引号和不带引号的同一字符串变量!你可以这样做。。。。
ejk8hzay4#
postgres(自9.0版起)允许使用任何受支持的服务器端脚本语言使用匿名块
http://www.postgresql.org/docs/current/static/sql-do.html
因为所有的东西都在一个字符串中,所以被替换的外部字符串变量需要被转义并引用两次。改用美元报价并不能完全防止sql注入。
wr98u20j5#
关于psql变量的最后一句话:
如果在sql语句中用单引号括起来,它们就不会展开。因此这不起作用:
要在sql语句中展开为字符串文字,必须在变量集中包含引号。但是,变量值必须用引号括起来,这意味着您需要第二组引号,并且必须转义内部的引号。因此,您需要:
编辑:从postgresql 9.1开始,您可以编写:
uqjltbpv6#
我用临时表解决了。
这样,我就有了一个可以在多个查询中使用的“变量”,这对于会话是唯一的。我需要它来生成唯一的“用户名”,但如果导入具有相同用户名的用户,仍然不会发生冲突。
9nvpjoqh7#
中的变量
psql
糟透了。如果要声明整数,必须输入整数,然后执行回车,然后以分号结束语句。观察:假设我要声明一个整数变量
my_var
把它放进一张table里test
:示例表
test
:显然,这张表中还没有任何内容:
我们声明一个变量。注意下一行的分号!
现在我们可以插入。我们得用这个奇怪的
:''
“查找语法:成功了!
说明:
所以。。。如果下一行没有分号怎么办?变量?看一看:
我们宣布
my_var
没有新线。让我们选择
my_var
.wtf是什么?不是整数,是字符串
999;
!eiee3dmh8#
我发现这个问题和答案非常有用,但也令人困惑。我很难让引用的变量工作,所以下面是我让它工作的方法:
这样就可以在一条语句中定义变量。使用它时,单引号将嵌入变量中。
注意!当我在引用的变量后面添加注解时,当我在其他答案中尝试某些方法时,它被作为变量的一部分吸入。那真的把我搞砸了。使用此方法时,注解似乎会像您期望的那样被处理。
x6492ojm9#
fwiw,真正的问题是我在\set命令的末尾加了一个分号:
\设置所有者密码'thepassword';
分号被解释为变量中的实际字符:
\echo:owner\u password密码;
所以当我尝试使用它时:
创建角色myrole登录未加密密码:owner_password noinherit createdb createrole有效期至'infinity';
…我知道了:
创建角色myrole登录未加密密码password;noinherit createdb createrole在“无限”之前有效;
这不仅无法在文本周围设置引号,而且还将命令分为两部分(第二部分是无效的,因为它以“noinherit”开头)。
这个故事的寓意是:postgresql“变量”实际上是用于文本扩展的宏,而不是真正的值。我相信这会派上用场,但一开始很棘手。
goqiplq210#
你可以试着用with子句。
weylhg0b11#
您需要使用过程语言之一,如pl/pgsql,而不是sqlproc语言。在pl/pgsql中,可以在sql语句中使用vars。对于单引号,可以使用quote literal函数。
zc0qhyus12#
我真的很怀念那个功能。实现类似功能的唯一方法就是使用函数。
我用了两种方法:
使用$\u共享变量的perl函数
将变量存储在表中
perl版本:
表格版本:
笔记:
plperlu比perl快
pg\u backend\u pid不是最好的会话标识,请考虑使用pid结合backend\u从pg\u stat\u活动开始
此表版本也不好,因为您必须偶尔清除它(而不是删除当前正在工作的会话变量)
q7solyqu13#
我在另一个线程上发布了一个新的解决方案。
它使用一个表来存储变量,并且可以随时更新。静态不可变getter函数是动态创建的(由另一个函数创建),由表的更新触发。你可以得到很好的表存储,加上不可变getter的极快速度。