![](/img/trans.png)
[英]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.