2017-12-02 147 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

相關(有詳細的說明):