【问题标题】:Selecting Columns From a Record Variable (PostgreSQL 8.4)从记录变量中选择列 (PostgreSQL 8.4)
【发布时间】:2012-07-21 15:15:31
【问题描述】:

我正在尝试从我从更新规则调用的函数中的记录变量中选择一列,并收到以下错误:

'无法识别记录数据类型中的列“名称”'

以下是我为产生错误所做的事情:

从更新规则中:

SELECT * INTO TEMPORARY TABLE TempTable FROM NEW;
SELECT MyFunction();

从 MyFunction() 内部

DECLARE RecordVar Record;
SELECT * INTO STRICT RecordVar FROM TempTable;
EXECUTE 'UPDATE AnotherTable SET column = $1.name' USING RecordVar;

注意:我意识到有更简单的方法可以实现上述代码的目标,但我简化了实际实现以专注于我遇到的问题,这开辟了其他可能的解决方案,但我真的如果可能的话,想让上面的代码工作。

【问题讨论】:

    标签: function postgresql variables record rule


    【解决方案1】:

    我刚刚想通了。我没有将 NEW 中的列插入到临时表中,而是将 NEW 记录作为单个列插入到临时表中,并在我的函数中将其称为 RecordVar."NEW"。我的规则和函数现在看起来像这样:

    从更新规则中:

    SELECT NEW AS "NEW" INTO TEMPORARY TABLE TempTable;
    SELECT MyFuction();
    

    从 MyFunction() 内部

    DECLARE RecordVar Record;
    SELECT * INTO STRICT RecordVar FROM TempTable;
    EXECUTE 'UPDATE AnotherTable SET column = $1.name' USING RecordVar."NEW";
    

    【讨论】:

      【解决方案2】:

      第二部分可以这样工作:

      DO
      $BODY$
      DECLARE
         RecordVar TempTable;
      BEGIN
         SELECT * INTO STRICT RecordVar FROM TempTable LIMIT 1;
         EXECUTE 'UPDATE AnotherTable  SET column = $1.name'
         USING RecordVar;
      END;
      $BODY$
      

      注意我如何使用表名作为类型。 PostgreSQL 自动为系统中的每个表创建一个复合类型。

      一个变量保存一行,SELECT 可以返回多行。除第一个之外的所有内容都将被丢弃。我添加了LIMIT 1 以澄清效果。我怀疑这就是你想要的。

      您可能不必在开始时就在规则中使用临时表。您可能想发布您的完整设置...

      【讨论】:

      • 您好欧文,非常感谢您的回复。我相信您的建议适用于一种情况,但我的问题是我有多个视图,每个视图都有自己的基础表,我想将我的函数应用到。如果我要将表指定为 RecordVar 的类型,我必须为每个表类型创建一个函数,我想避免这种情况。很抱歉没有在我原来的问题中包含这些信息。
      • 关于我对临时表的使用,我只是将它们用作将规则内的 NEW 和 OLD 交换到我的函数的机制,因为您不能将数据类型记录传递给功能。如果有更好的方法将 NEW 和 OLD 从规则传递给函数,那么这样做可能会解决我的问题。我不明白的一件事是为什么我可以在规则或触发器的上下文中使用 NEW. 知道 NEW 属于记录数据类型但不是 RecordVar.,我已经从中填充NEW 的一个实例。
      • 我尝试了以下组合,导致“记录类型尚未注册”或“无法将类型记录转换为 ”:EXECUTE 'UPDATE AnotherTable SET column = $1.name ' 使用 RecordVar::Table; EXECUTE 'UPDATE AnotherTable SET column = $1.name' USING ROW(RecordVar.*)::Table;我认为以下方法会起作用,但它也不起作用: CREATE TEMPORARY TABLE YetAnotherTable (Like Table);插入 YetAnotherTable (SELECT * FROM TempTable);选择 * 从 YetAnotherTable 到 RecordVar; EXECUTE 'UPDATE AnotherTable SET column = $1.name' USING RecordVar::YetAnotherTable;
      猜你喜欢
      • 2011-02-08
      • 1970-01-01
      • 2020-08-17
      • 2014-09-16
      • 2010-10-08
      • 2015-10-09
      • 2020-09-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多