postgresql - postgres (8.3),在函数中使用查询结果

标签 postgresql stored-procedures tcl

我正在尝试创建一个函数来填充 2 个表,第二个查询包含来自第一个插入的新 ID。

我的一些表格的示例:

CREATE TABLE message
(
  message_id bigserial NOT NULL,
  member_id bigint NOT NULL,
  message character varying(8192) NOT NULL,
  ...
)

CREATE TABLE feed_message
(
  feed_id bigint NOT NULL,
  message_id bigint NOT NULL
)

我想做的是在消息表中插入一条新消息,并使用生成的 message_id 填充 feed_message 表

我尝试使用 pltcl 语言编写一个函数,但我不知道如何使用 SPI_getvalue 来获取刚刚创建的 tupil

这是我目前所拥有的:

/* message_post(entity, id, member_id, title, message, reactionTo) */
CREATE OR REPLACE FUNCTION message_post ()
 RETURNS VOID
 LANGUAGE pltcl
AS $BODY$
 ret_status = spi_exec -count 1 "INSERT INTO message (member_id, title, message) VALUES ($3, $4, $5)"
 IF (ret_status == SPI_OK_SELECT && SPI_processed > 0) {
  //get the tupil from *SPI_tuptable
  set message_id <the new message_id>
 }
 spi_exec -count 1 "INSERT INTO $1_message ($1_id, message_id) VALUES ($2,$message_id)"
$BODY$;

/* useage */
SELECT message_post('feed',12,1,'title','message');

最佳答案

您的 Tcl usage 有几个地方(PL/Tcl 可以被认为是一种方言,带有包装)是完全错误的。我猜这是正确的,基于 examples in the PL/Tcl documentation .

CREATE OR REPLACE FUNCTION message_post(text,integer,integer,text,text)
RETURNS VOID AS $$
   set ret_status [spi_exec -count 1 \
         "INSERT INTO message (member_id, title, message) \
               VALUES ($3, '[quote $4]', '[quote $5]')"]
   if {$ret_status > 0} {
      set message_id [spi_lastoid]
      spi_exec -count 1 "INSERT INTO ${1}_message (${1}_id, message_id) \
                         VALUES ($2, $message_id)"
   }
$$ LANGUAGE pltcl;

但是,我不认为这是惯用的!毕竟,它正在做 quote 和其他类似的事情。据我了解,这样更好:

CREATE OR REPLACE FUNCTION message_post(text,integer,integer,text,text)
RETURNS VOID AS $$
   # Precompile the INSERTs if they didn't already exist
   if {![info exists GD(post_message_plan)]} {
      set GD(post_message_plan) [spi_prepare \
            {INSERT INTO message (member_id, title, message) VALUES ($1, $2, $3)} \
            {integer text text}]
   }
   if {![info exists GD(assoc_message_plan:$1)]} {
      set GD(assoc_message_plan:$1) [spi_prepare \
            "INSERT INTO ${1}_message (${1}_id, message_id) VALUES (\$1, \$2)" \
            {integer integer}]
   }
   # Run the pair of INSERTs
   if {[spi_execp -count 1 $GD(post_message_plan) [list $3 $4 $5]] > 0} {
      spi_execp -count 1 $GD(assoc_message_plan:$1) [list $2 [spi_lastoid]]
   }
$$ LANGUAGE pltcl;

其他需要注意的事项:我相信您要查找消息ID 的是spi_lastoid,我实际上并没有检查您的SQL 是否正确。另外,我可能对各种错误的参数类型有误。 (PostgreSQL 和 Tcl 对于什么是类型有着截然不同的想法。)

关于postgresql - postgres (8.3),在函数中使用查询结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3831286/

相关文章:

java - 逆向工程错误的字符编码

postgresql - 如何为 postgres docker 容器的初始化脚本指定当前工作数据库?

mysql - 从 VBA 调用 mySQL 存储过程 (Excel 2013)

tcl - .tbc 到 .tcl 文件

tcl - lappend 向元素添加花括号

django - 我可以让 Django-1.2 透明地使用我的 LATIN1 编码的 PostgreSQL 数据库吗?

postgresql - PostgreSQL 的 pg_stat_all_indexes 表中的统计信息存储多长时间?

asp.net - 在前端捕获从 sql server 存储过程返回的错误消息

performance - 存储过程执行时间不正确

if-statement - Expect 脚本中的“if else”语句