无法使用pl \ pgSQL过程插入值

时间:2017-12-02 22:21:01

标签: sql postgresql sql-insert plpgsql upsert

我的手术有问题。我们有2个表:公司和类型公司。公司有3列(“companyid”,“companyname”,“typeofcompany”),typeof公司有2列(“typeofcompanyId”,“typeofcompany”);

这是我在公司中插入值的代码:

 CREATE OR REPLACE FUNCTION insert_to_companies(c_name VARCHAR(255),toc INTEGER)
      RETURNS VOID AS $$
          DECLARE i integer;
           BEGIN
          FOR i IN SELECT "typeofcompanyId" FROM typeofcompanies LOOP
            IF toc = i THEN insert into public.companies(companyname, typeofcompany) VALUES (c_name,toc);
              END IF;
          END LOOP;
          IF(SELECT companyname FROM companies WHERE companyname = c_name) = NULL THEN insert into public.typeofcompanies(typeofcompany) VALUES (toc);
                                                                             INSERT into public.companies(companyname,typeofcompany) VALUES (c_name,toc);
          END IF;
          END;
    $$ LANGUAGE plpgsql VOLATILE;

因此,如果我们没有typeofcompany,我们应该创建它。但是当我选择insert_to_companies(“1”,5);我采取错误:列“1”不存在。所以我认为这是一个非常容易的问题,但我花了3个多小时才发现问题。拜托,我需要帮助......

使用liquibase创建表的代码

公司

<databaseChangeLog xmlns = "http://www.liquibase.org/xml/ns/dbchangelog/1.9" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog/1.9
                      http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-1.9.xsd">
    <changeSet id="1" author="tiurinvalery@gmail.com" runOnChange="true" >
        <createTable tableName ="companies">
            <column autoIncrement = "true" name = "companyid" type ="BIGINT">
                <constraints primaryKey ="true"></constraints>
            </column>
            <column name="companyname" type="VARCHAR(255)">
            </column>
            <column name="typeofcompany" type="INTEGER">
            </column>
        </createTable>
    </changeSet>
 </databaseChangeLog>

适用于公司类型:

<databaseChangeLog xmlns = "http://www.liquibase.org/xml/ns/dbchangelog/1.9" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog/1.9
                      http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-1.9.xsd"  >
    <changeSet id="5" author="tiurinvalery@gmail.com" runOnChange="true" >
        <createTable tableName ="typeofcompanies">
            <column autoIncrement = "true" name = "typeofcompanyId" type ="BIGINT">
                <constraints nullable="false" primaryKey="true"></constraints>
            </column>
            <column name = "typeofcompany" type="VARCHAR(255)">
                <constraints nullable="false"></constraints>
            </column>
        </createTable>
    </changeSet>
</databaseChangeLog>

1 个答案:

答案 0 :(得分:0)

表定义可能如下所示:

CREATE TABLE company_type (
   company_type_id serial PRIMARY KEY
 , company_type    text UNIQUE NOT NULL
); 

CREATE TABLE company (
   company_id      serial PRIMARY KEY
 , company         text NOT NULL
 , company_type_id int REFERENCES company_type
);

我做了一些改变:

  • 不使用双引号CaMeL案例名称。如果可以,请避免这样做。
  • 使用integer代替bigint获取PK ID。我怀疑你会在本世纪用公司类型耗尽关键空间......
  • 仅使用textvarchar(255)通常是对Postgres的误解。

最佳功能(或仅查询)在很大程度上取决于您的使用案例。数据库负载,并发性,确切要求。如果可以进行并发写入,我建议这样做以避免竞争条件:

CREATE OR REPLACE FUNCTION f_insert_to_companies(_c_name text, _toc text)
  RETURNS void AS
$func$
BEGIN
LOOP
   INSERT INTO company(company, company_type_id)
   SELECT _c_name, t.company_type_id
   FROM   company_type t
   WHERE  company_type = _toc;

   EXIT WHEN FOUND;

   -- if type is missing, insert and keep looping    
   INSERT INTO company_type (company_type)
   VALUES (_toc)
   ON     CONFLICT (company_type) DO NOTHING;
END LOOP;
END
$func$ LANGUAGE plpgsql;

dbfiddle here

相关(详细说明):