[英]Is it possible to prevent SQL injection without prepared statements (Node.js & MSSQL)
[英]Transaction for prepared statements using Node mssql
我想创建一个 Express REST API,并将使用 MSSQL 作为数据库部分。 我使用mssql模块并使用PreparedStatement
类。
有时我的查询必须是事务性的,所以我也必须使用Transaction
类。
我在这里找到了一些关于准备好的语句和事务的信息,但不知道如何使用准备好的语句执行事务查询。
有人介意解释如何在事务中使用带有准备好的语句的 mssql 模块吗? 我的查询功能应该提供一个功能,允许在我的查询文件中写入这样的内容
所以要重现这个问题:首先,我创建了一个数据库,其中包含一个名为“整数”的表和一个数字列“值”。
然后我使用以下代码创建了一个空的 Node/Typescript 项目:
import sql, { ConnectionPool, PreparedStatement } from 'mssql';
class App {
private connectionPool: ConnectionPool;
constructor() {
this.connectionPool = new sql.ConnectionPool(databaseConfig);
}
public run = async (): Promise<void> => {
try {
await this.connectionPool.connect();
const preparedStatement: PreparedStatement = new sql.PreparedStatement(this.connectionPool);
preparedStatement.input('number', sql.Numeric(18, 0));
await preparedStatement.prepare('INSERT INTO integer (value) VALUES (@number)');
await preparedStatement.execute({ number: 1 });
await preparedStatement.unprepare();
console.log('done...');
} catch (error) {
throw error;
}
}
}
(async () => {
const app: App = new App();
await app.run();
})().catch(error => {
throw error;
});
到现在为止还挺好。 现在我想在一个事务中运行两个 INSERT,但第二个传入一个字符串,所以我预计会出现错误并且第一个被回滚。 我更新的run
功能:
public run = async (): Promise<void> => {
try {
await this.connectionPool.connect();
const transaction: Transaction = new sql.Transaction(this.connectionPool);
const workingStatement: PreparedStatement = new sql.PreparedStatement(transaction);
workingStatement.input('number', sql.Numeric(18, 0));
const invalidStatement: PreparedStatement = new sql.PreparedStatement(transaction);
invalidStatement.input('number', sql.Numeric(18, 0));
try {
await transaction.begin();
await workingStatement.prepare('INSERT INTO integer (value) VALUES (@number)');
await workingStatement.execute({ number: 1 });
await workingStatement.unprepare();
await invalidStatement.prepare('INSERT INTO integer (value) VALUES (@number)');
await invalidStatement.execute({ number: false });
await invalidStatement.unprepare();
await transaction.commit();
} catch (error) {
await transaction.rollback();
console.log('execution failed...');
}
console.log('done...');
} catch (error) {
throw error;
}
}
现在我收到这个错误
(节点:18416)未处理的PromiseRejectionWarning:TransactionError:无法回滚事务。 有一个请求正在进行中。
而且我不确定我的语法是否错误。
我相信您遇到的错误是因为您没有按照文档中的建议调用unprepare
:
请记住,在调用 unprepare 之前,您无法执行事务中的其他请求
在回滚事务之前对语句调用unprepare
对我有用:
try {
// ...
await invalidStatement.prepare('INSERT INTO integer (value) VALUES (@number)');
try {
await invalidStatement.execute({ number: false });
} finally {
await invalidStatement.unprepare();
}
} catch (error) {
// rollback here...
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.