【问题标题】:How to insert multiple records from JSON API call to SQL Server table如何将 JSON API 调用中的多条记录插入 SQL Server 表
【发布时间】:2021-09-19 22:35:05
【问题描述】:

下面的代码来自我正在设置的 api(第一次),我在接受进入端点的 JSON 数组时遇到了此设置的问题。我正在使用 Postman 进行测试。对于多个端点,我希望能够接受要插入数据库等的数据数组,但我不确定如何达到这一点。

当我尝试在帖子正文中执行以下操作时:

     [
        {
            "proofID": 999,
            "client": "someJob999",
            "runSeq": 1000,
            "result": null
        },
        {
            "proofID": 1000,
            "client": "someJob1000",
            "runSeq": 10001,
            "result": null
        }
    ]

我返回了单个插入行的自动递增 id,其值为空值,如下所示:

[
    [
        {
            "ID": 61,
            "proofID": null,
            "client": null,
            "runSeq": null,
            "result": null
        }
    ]
]

以下所有代码都与构建 api 相关。

//////////JobData_dbconfig.js//////////
const sql = require('mssql/msnodesqlv8');
require('dotenv').config();

const configJobData = {
    user: process.env.SQL_USER,
    password: process.env.SQL_PASS,
    server: process.env.SQL_SERVER,
    database: process.env.SQL_DB1,
    driver: 'msnodesqlv8',
    options: {
        trustedconnection: true,
        enableArithAort: true,
    },
    port: process.env.SQL_PORT1
}

module.exports = configJobData;


//////////classes.js/////////////
            class proofs{
                constructor(ID,proofID,runSeq,client,result){
                    this.ID = ID;
                    this.proofID = proofID;
                    this.runSeq = runSeq;
                    this.client = client;
                    this.result = result;
                }
            }  
            
            module.exports = {
                proofs: proofs
            };
    
//////////SQL Stored Procedure/////////
    USE [JobData2]
    GO
    /****** Object:  StoredProcedure [dbo].[insertProof]    Script Date: 7/9/2021 10:38:41 AM ******/
    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    ALTER PROCEDURE [dbo].[insertProof] @proofID int, @runSeq int, @client varchar(75), @result varchar(15)
    AS
    INSERT INTO JobData2.dbo.Proofs (proofID,runSeq,client,result)
    OUTPUT Inserted.[ID], Inserted.[proofID], Inserted.[client], Inserted.[runSeq], Inserted.[result]
    VALUES (@proofID,@runSeq,@client,@result)
    
    
            
//////////dboperations.js////////////
                require('dotenv').config()
                
                var configJobData = require('./JobData_dbconfig');
                const sql = require('mssql/msnodesqlv8');
                    
                async function addProof(proof){
                    try{
                        let pool = await sql.connect(configJobData);
                        let insertProof = await pool.request()
                            .input('proofID', sql.Int, proof.proofID)
                            .input('runSeq', sql.Int, proof.runSeq)
                            .input('client', sql.VarChar, proof.client)
                            .input('result', sql.VarChar, proof.result)
                            .execute('insertProof');
                
                        return insertProof.recordsets;
                    }
                    catch (error){
                        console.log(error);
                    }
                }
                
                module.exports = {
                    addProof: addProof
                }
        
///////////application////////////
            require('dotenv').config()
            
            const express = require('express')
            var cors = require('cors')
            const app = express()
            
            
            //rate limiter
            const rateLimit = require('express-rate-limit')
            const limiter = rateLimit({
                windowMs: process.env.svrLimit, //30 min
                max: process.env.svrMax, //limit each IP to 100 requests per 30min
                message: "Too many requests from this IP in the last 30 min, please try again later."
            })
           
            
            //db 
            const dboperations = require('./dboperations')
            var configJobData = require('./JobData_dbconfig')
            var configEliteMaster = require('./EliteMaster_dbconfig')
            const dbclasses = require('./models/db/classes')
            
            //app
            app.use(express.json())
            app.use(cors())
            
            //app post endpoint
            app.post('/api/proofs', limiter, (req,res) => {
                let proof = { ...req.body }
                dboperations.addProof(proof).then(result => {
                    //console.log(result);
                    res.status(201).json(result);
                })
            })
            
            
            var port = process.env.PORT || 8090
            app.listen(port)
            console.log('server is running at port ' + port)
     ```   

【问题讨论】:

  • 我相信问题可能出在我的 SQL 存储过程中,但我不确定如何将其修改为动态并接受少至 1 或多至 JSON 有效负载中提供给端点的数量。

标签: node.js arrays json sql-server rest


【解决方案1】:

我今天通过以下操作解决了这个问题:

  1. 修改了我的sql存储过程如下:
        USE [JobData2]
    GO
    
    /****** Object:  StoredProcedure [dbo].[addProofs]    Script Date: 7/20/2021 4:53:55 PM ******/
    SET ANSI_NULLS ON
    GO
    
    SET QUOTED_IDENTIFIER ON
    GO
    
    ALTER PROCEDURE [dbo].[addProofs] @proofs nvarchar(max)
    AS
    DECLARE @json nvarchar(max) = @proofs
    INSERT INTO JobData2.dbo.Proofs (proofID, runSeq, client, result)
    OUTPUT Inserted.[ID], Inserted.[proofID], Inserted.[runSeq], Inserted.[client], Inserted.[result]
     SELECT * 
     FROM OPENJSON(@json)
     WITH (proofID int, runSeq int, client varchar(75), result varchar(15))
    GO
  1. 将我的 dboperation 函数修改为:
async function addProof(proof){
    try{
        let pool = await sql.connect(configJobData);
        let insertProof = await pool.request()
            .input('proofs', sql.NVarChar, proof)
            .execute('addProofs');

        return insertProof.recordsets;
    }
    catch (error){
        console.log(error);
    }
}
  1. 修改了我的端点设置如下:
router.post('/', publimiter, authenticateToken, (req,res) => {
    let proof = JSON.stringify(req.body)
            dboperations.addProof(proof).then(result => {
            //console.log(result);
            res.status(201).json(result);
    })
})

本质上,这是设置“证明”以在端点被命中时包含整个请求主体,然后通过 dboperations 作为参数将其作为“证明”传递给存储过程,然后在存储中使用 OPENJSON proc,将数组中的每个对象集插入到数据库中,并将插入的数据返回给用户。

无论如何,这对于经验丰富的开发人员来说可能很常见,但我希望它可以帮助像我这样的其他新手!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-09
    • 2021-09-03
    • 2016-08-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多