【问题标题】:Why is json_populate_record() not recognizing row type?为什么 json_populate_record() 不能识别行类型?
【发布时间】:2018-03-01 07:55:05
【问题描述】:

我有 2 张桌子 typename。我试图通过一个函数用 json_populate_record() 插入这些。收到以下错误:

first argument of json_populate_record must be a row type

type 是使用以下方法创建的:

CREATE TABLE IF NOT EXISTS "type" (
  "id"    TEXT NOT NULL,
  "value" TEXT NOT NULL,
  PRIMARY KEY ("id"),
  CHECK ("id"<>'' AND "value"<>'')
);
CREATE INDEX IF NOT EXISTS "idx_type_value"
ON "type" ("value");


CREATE OR REPLACE FUNCTION "type_insertone" (
  IN _a JSON
) RETURNS VOID AS $$
BEGIN
  INSERT INTO "type" SELECT * FROM json_populate_record(NULL::"type", _a);
END;
$$ LANGUAGE plpgsql;

name 是使用以下方法创建的:

CREATE TABLE IF NOT EXISTS "name" (
  "id"    TEXT NOT NULL,
  "value" TEXT NOT NULL,
  PRIMARY KEY ("id"),
  CHECK ("id"<>'' AND "value"<>'')
);
CREATE INDEX IF NOT EXISTS "idx_name_value"
ON "name" ("value");


CREATE OR REPLACE FUNCTION "name_insertone" (
  IN _a JSON
) RETURNS VOID AS $$
BEGIN
  INSERT INTO "name" SELECT * FROM json_populate_record(NULL::"name", _a);
END;
$$ LANGUAGE plpgsql;

当用{id: 'x', 'value': 'x'} 调用type_insertone() 时,它可以工作。 但是当我对name_insertone() 做同样的事情时,它不起作用!

我在想是否有可能在创建表之前创建函数,这可能导致它不知道表name,但我认为不是这样。

我不知道我应该在这里尝试什么。我还检查了name 不是保留关键字,type 也是。

【问题讨论】:

    标签: sql postgresql plpgsql postgresql-9.6 node-postgres


    【解决方案1】:

    “name”是文本类型and a key word:

    https://www.postgresql.org/docs/current/static/datatype-character.html 看底部,所以当您转换为“名称”时,您转换为名称数据类型,而不是您的表行类型...

    例如:

    t=# alter table name rename to name1;
    ALTER TABLE
    t=# CREATE OR REPLACE FUNCTION "name_insertone" (
      IN _a JSON
    ) RETURNS VOID AS $$
    BEGIN
      INSERT INTO "name1" SELECT * FROM json_populate_record(NULL::"name1", _a);
    END;
    $$ LANGUAGE plpgsql;
    CREATE FUNCTION
    t=# select name_insertone('{"id": "x", "value": "x"}');
     name_insertone
    ----------------
    
    (1 row)
    

    然而:

    t=# create table text(i int);
    CREATE TABLE
    t=# SELECT * FROM json_populate_record(NULL::"text", '{}')
    t-# ;
    ERROR:  first argument of json_populate_record must be a row type
    t=# create table char(i int);
    CREATE TABLE
    t=# SELECT * FROM json_populate_record(NULL::"char", '{}');
    ERROR:  first argument of json_populate_record must be a row type
    

    【讨论】:

    • 但是"name" 应该和name 不同?
    • 这里不确定。我只是避免使用名称作为名称,尤其是当您想将其用作行类型时
    • 坦率地说我的知识在这里非常有限,但是如果您尝试使用 text、char、varchar 作为名称创建表格,您会遇到相同的ERROR: first argument of json_populate_record must be a row type 尝试将 null 转换为 rowtype。也许劳伦兹会路过并解释为什么会这样?..
    • 当然,不用担心 - 有趣的是,具有相同名称的显式强制转换的候选顺序是什么,我猜 pg_cast 无论如何都会排在第一位,但在文档中找不到它
    • 我想你是在建议一些它仍然可以工作的方法,但我不明白。当我尝试这个时,我假设name 一定不是关键字,因为它在列表中列为非保留关键字。我什至不会搜索这个,因为我假设默认情况下双引号表示标识符,即使存在这样的关键字也没关系,但在这种情况下确实如此。
    猜你喜欢
    • 2020-05-25
    • 2018-08-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-27
    • 2015-12-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多