【问题标题】:PostgresQL: Insert with key-value instead of two listsPostgresQL:插入键值而不是两个列表
【发布时间】:2016-02-19 01:12:47
【问题描述】:

PostgresQL 允许您插入两个列表,一个是字段名称,另一个是值。

INSERT INTO products (product_no, name, price) VALUES (1, 'Cheese', 9.99);

对于长列表,很难确定您所在的列表索引。有没有办法通过在值旁边指定列名来插入,即键值对?注意:这与hstore 不同。

即。

INSERT INTO products (product_no => 1, name => 'Cheese', price => 9.99);

【问题讨论】:

    标签: postgresql postgresql-9.2


    【解决方案1】:

    常规的 DML 是不可能的。

    作为替代方案:

    使用值列表使 DML 更短:

    INSERT INTO products (product_no, name, price) VALUES
      (1, 'Cheese', 9.99),
      (2, 'Sausages', 9.99),
      ...;
    

    或者创建可以通过指定参数执行的函数:

    create or replace function insert_product(
      in product_no products.product_no%type, 
      in name products.name%type, 
      in price products.price%type) returns products.product_no%type as $$
      insert into products(product_no, name, price) values (product_no, name, price) returning product_no;
    $$ language sql;
    
    select insert_product(1, 'Mashrooms', 1.99); -- Parameters by order 
    select insert_product(product_no := 2, name := 'Cheese', price := 9.99); -- Parameters by name
    select insert_product(product_no := 3, price := 19.99, name := 'Sosages'); -- Order does mot matter
    

    【讨论】:

      【解决方案2】:

      我创建了一个供我使用。下面以json作为输入并创建动态SQL查询并执行。

      示例用法

      create table employee(name character varying(20), address character varying(100), basic integer);
      
      --sample call-1
      call insert_into(true, 'employee', '{
          "name"      : "''Ravi Kumar''",
          "address"   : "''#1, 2nd Cross, Bangalore''",
          "basic"     : 35000
      }',
      '');
      
      --sample call-2
      call insert_into(true, 'employee', '{
          "name"      : "eo.name",
          "address"   : "eo.address",
          "basic"     : "eo.basic"
      }',
      '
      from employee_old eo
      ');
      

      程序

      CREATE or REPLACE PROCEDURE insert_into(
          debug BOOLEAN,
          tableName TEXT,
          jsonTxt json,
          fromWhere TEXT
      )
      LANGUAGE plpgsql
      as $$
      DECLARE
          field TEXT;
          fieldQuery TEXT;
          valueQuery TEXT;
          finalQuery TEXT;
          noOfRecords INT;
      BEGIN 
          IF debug THEN
              raise notice 'preparing insert query';
          END IF;
          
          fieldQuery := CONCAT('INSERT INTO ', tableName, '(', E'\n');
          valueQuery := CONCAT('SELECT ', E'\n');
          
          FOR field IN SELECT * FROM json_object_keys(jsonTxt)
          LOOP
              fieldQuery := CONCAT(fieldQuery, field, E',\n');
              valueQuery := CONCAT(valueQuery, json_extract_path_text(jsonTxt, field), E',\n');
              
          END LOOP;
          fieldQuery := RTRIM(fieldQuery, E',\n');
          fieldQuery := CONCAT(fieldQuery, ')');
          
          valueQuery := RTRIM(valueQuery, E',\n');
          
          finalQuery := CONCAT(fieldQuery, E'\n', valueQuery, E'\n', fromWhere, ';');
          
          IF debug THEN
              RAISE NOTICE 'query:: %',  finalQuery;
          END IF;
          
          EXECUTE finalQuery;
          get diagnostics noOfRecords = row_count;
          RAISE NOTICE 'Inserted:: %',  noOfRecords;
      END
      $$;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-02-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-08-30
        • 2010-09-17
        相关资源
        最近更新 更多