2017-12-02 116 views
0

我的程序有问题。我们有2个表格:公司和typeofcompanies。公司有3列(“公司名称”,“公司名称”,“公司名称”),公司类型有2列(“typeofcompanyId”,“typeofcompany”);无法使用pl pgSQL过程插入值

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

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="[email protected]" 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="[email protected]" 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> 
+0

最低要求对于这种问题:表定义('CREATE TABLE'语句sh由于数据类型和约束)以及您的Postgres版本。只列出你的列不是很有用。 –

+0

Okey对不起,我应该用liquibase创建我的表,所以这是liquibase代码: –

+0

Liquibase与这个问题无关。请显示SQL代码。而且我仍然无法看到您的Postgres版本。 ('SELECT version()')并且澄清'c_id +“_ type”'来自哪里以及它应该做什么。 –

回答

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 
); 

我做了一些改动:

  • 不使用双引号驼峰名。如果可以的话,避免这种情况。
  • 使用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

相关(有详细的说明):