PostgreSQL-在从JSON和一个表中选择值的同时插入两个表

时间:2018-08-10 19:05:03

标签: json postgresql insert

需要一些想法。

我正在尝试从nodejs应用程序将值插入两个表中,我想同时将数据插入两个表中,因为我将第二个表的列中的第一个表的ID用作父ID。 这是表结构

表1

export class Form extends Component {
constructor(props) {
    super(props);
    this.state = {
        userInfo: {
            name: '',
            email: '',
            phone: ''
        },
        errors: {}
    };

    this.handleInput = this.handleInput.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
}

handleInput(e) {
    let fields = this.state.userInfo;
    fields[e.target.name] = e.target.value;        
    this.setState({fields});
}

validateForm() {

    let fields = this.state.userInfo;
    let errors = {};
    let formIsValid = true;

    if (!fields["name"]) {
      formIsValid = false;
      errors["name"] = "*Please enter your name.";
    }

    if (typeof fields["name"] !== "undefined") {
      if (!fields["name"].match(/^[a-zA-Z ]*$/)) {
        formIsValid = false;
        errors["name"] = "*Please enter alphabet characters only.";
      }
    }

    if (!fields["email"]) {
      formIsValid = false;
      errors["email"] = "*Please enter your email.";
    }

    if (typeof fields["email"] !== "undefined") {
      //regular expression for email validation
      var pattern = new RegExp(/^(("[\w-\s]+")|([\w-]+(?:\.[\w-]+)*)|("[\w-\s]+")([\w-]+(?:\.[\w-]+)*))(@((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$)|(@\[?((25[0-5]\.|2[0-4][0-9]\.|1[0-9]{2}\.|[0-9]{1,2}\.))((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})\.){2}(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})\]?$)/i);
      if (!pattern.test(fields["email"])) {
        formIsValid = false;
        errors["email"] = "*Please enter valid email.";
      }
    }

    if (!fields["phone"]) {
      formIsValid = false;
      errors["phone"] = "*Please enter your phone.";
    }

    if (typeof fields["phone"] !== "undefined") {
      if (!fields["phone"].match(/^[0-9]{10}$/)) {
        formIsValid = false;
        errors["phone"] = "*Please enter valid phone.";
      }
    }

    this.setState({
      errors: errors
    });
    return formIsValid;


  }

handleSubmit(event) {
    event.preventDefault();
    if (this.validateForm()) {
        let fields = {};
        fields["name"] = "";
        fields["email"] = "";
        fields["phone"] = "";
        this.setState({fields:fields});
        alert("Form submitted");
    }

    let formData = {
        name: this.state.userInfo.name,
        emailAddress: this.state.userInfo.email,
        phoneNumber: this.state.userInfo.phone
    }

    let fullname = this.state.userInfo.name.split(' ');

       switch (fullname.length) {
           case 1:
               formData.firstname = fullname[0];
               break;
           case 2:
               formData.firstname = fullname[0];
               formData.lastname = fullname[1];
               break;
           case 3:
               formData.firstname = fullname[0];
               formData.lastname = fullname[2];
               break;
           default:
               formData.firstname = fullname[0];
               formData.lastname = fullname[2];
       }

       const json = JSON.stringify(formData);

    fetch(submissionUrl, {
        method: 'POST',
        body: json,
        headers: {
            "Accept": "application/json",
            "Content-Type": "application/json"
          }
    }).then(response => {
        if (response.status >= 200 && response.status < 300) {
            return response;
            console.log(response);
            window.location = 'www.someurl.com';
          } else {
           console.log('Somthing went wrong');
          }
    });

}

render() {
    return (
       <form onSubmit={this.handleSubmit} method="post">
          <div>
             <input 
               type="text" 
               name="name" 
               id="name" 
               placeholder="John Smith" 
               tabIndex="1" 
               minLength="2" 
               value={this.state.userInfo.name} 
               onChange={this.handleInput} 
               required="required" 
             />
             <span className="error">{this.state.errors.name}</span>
             <label htmlFor="name">Full name*</label>
          </div>
          <div>
             <input 
               type="text" 
               name="email" 
               id="email" 
               placeholder="john@company.com" 
               tabIndex="2" 
               minLength="5" 
               value={this.state.userInfo.email} 
               onChange={this.handleInput} 
               required="required" 
             />
             <span className="error">{this.state.errors.email}</span>
             <label htmlFor="name">Email*</label>
          </div>
          <div>
             <input 
               type="tel" 
               name="phone" 
               id="phone" 
               placeholder="(___)___-____" 
               tabIndex="3" 
               minLength="9" 
               value={this.state.userInfo.phone} 
               onChange={this.handleInput} 
               required="required" 
             />
             <span className="error">{this.state.errors.phone}</span>
             <label htmlFor="name">Phone*</label>
          </div>
          <button id="submitBtn" type="submit">Submit Form</button>
       </form>
    )
}

表2:

                                  Table “public.table1”
   Column    |     Type      | Collation | Nullable |                Default
-------------+---------------+-----------+----------+---------------------------------------
 id          | integer       |           | not null | nextval(‘table1_id_seq’::regclass)
 name        | text          |           | not null |
 description | character(50) |           |          |
Indexes:
    “table1_pkey” PRIMARY KEY, btree (id)

我正在以UI的形式获取JSON值

                                  Table “public.table2”
   Column    |     Type      | Collation | Nullable |              Default
-------------+---------------+-----------+----------+-----------------------------------
 id          | integer       |           | not null | nextval(‘table2_id_seq’::regclass)
 name        | text          |           | not null |
 parent_id   | text          |           | not null |
 sequence    | integer       |           | not null |
 description | character(50) |           |          |

我编写了以下查询,但出现以下错误:

{“table1”:{“name”:“test”,“description”:“test123”,“table2”:[{“column1”:“WMS”,“column2”:“WMS”,“column3”:2,“column4":“rtest”}]}}

错误:

WITH new_table1 AS(
  INSERT INTO TABLE1
      (id, name, description)
    VALUES
      (nextval('table_sequence'), 'BDO', 'Sample test') returning id
) INSERT INTO TABLE2(id,parent_id,name,sequence,description)  (  
  nextval('table2_sequence'), 
  (select id from new_table1), 
  (select column1, column3, column4
from jsonb_to_recordset(
    '[{"column1":"WMS","column2":"WMS","column3":2,"column4":"rtest","icon":"sap-icon://it-host"}]'
) r (column1 text, column2 text,column3 int, column4 text, icon text)) );

1 个答案:

答案 0 :(得分:0)

错误的根源是,您只能在VALUES列表中使用标量表达式(返回单个列的子查询)(您也错过了该关键字)。您可以这样解决此问题:

WITH new_table1 AS (
  INSERT INTO table1 (name, description)
  VALUES ('BDO', 'Sample test') RETURNING id )
INSERT INTO table2 (parent_id, name, sequence, description)   
  SELECT id, column1, column3, column4
  FROM new_table1,
       jsonb_to_recordset (
         '[{"column1":"WMS","column2":"WMS","column3":2,"column4":"rtest","icon":"sap-icon://it-host"}]'
       ) r (column1 text, column2 text,column3 int, column4 text, icon text);

解决方案在于使用带有INSERT语句而不是VALUES子句的查询。在查询中,将INSERT上的table1语句与jsonb_to_recordset()的输出合并。这是笛卡尔积,但是由于INSERT仅产生一行,所以没有问题。

还请注意,我已经删除了对id列及其序列的引用-默认值的优点是,插入时不必指定任何内容...