簡體   English   中英

在 NestJS 中執行 Oracle 數據庫存儲過程

[英]Execute an Oracle DB stored procedure In NestJS

我正在嘗試通過我的 NestJS api 運行一個 Oracle 存儲過程。我一直在關注 NestJS 數據庫文檔,但它沒有專門為您提供調用存儲過程所需語法的任何幫助。 存儲過程的位置也有點奇怪,你必須go進入數據庫,到其他用戶,然后到用戶,然后到那個用戶的過程文件夾,在那里我可以訪問我需要的過程(見下圖) . 在此處輸入圖像描述

當我嘗試在數據庫中運行該過程時,它顯示它需要 startTime 和 endTime 作為參數,當我輸入 hover 時,它給了我格式,這是我通過我的服務傳遞的格式。 在此處輸入圖像描述 在此處輸入圖像描述

這是我的應用程序模塊:

@Module({
  imports: [

  ConfigModule.forRoot({
      envFilePath: ['.env.development.local'],
      isGlobal: true
    }),
    TypeOrmModule.forRoot({
      type: 'oracle',
      host: process.env.OMSRECON_DB_HOST,
      port: parseInt(process.env.OMSRECON_DB_PORT),
      username: 'FAKE_USER',
      password: 'FAKE_PASSWORD',
      database: process.env.OMSRECON_DB_DATABASE,
      sid: process.env.OMSRECON_DB_SID,
      entities: [OmsReconData],
      synchronize: false
    }),
    CustomerOutagesModule,
    UserModule,
    SystemStatusesModule,
    SystemIncidentsModule
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

這是我的服務模塊:

@Module({
  imports: [
    TypeOrmModule.forFeature([OmsReconData])
  ],
  controllers: [CustomerOutagesController],
  providers: [CustomerOutagesService]
})
export class CustomerOutagesModule {}

這是我的 service.ts:

@Injectable()
export class CustomerOutagesService {
  constructor(
    @InjectConnection('omsrecon')
    private connection: Connection,
  ) {}

  async getAll() {
    const data = await this.connection.manager
      .query('EXEC OMSRECON.GET_OMS_RECON_DATA @0 @1', ['20220716', '20220717'])
      .then((res) => console.log(res))
      .catch((error) => console.log(error));
    console.log(data);
    return 'test';
  }
}

我真的只需要弄清楚運行存儲過程需要什么語法以及如何訪問其他用戶存儲過程? 先謝謝您的幫助。

更新** 我不確定它是否真的在運行存儲過程,但我現在在運行我的代碼時收到 QueryFailedError: ORA-01036: illegal variable name/number。

我想我會用這個

await this.connection.query(
  'EXEC ProcedureName @0', [
    param0
  ]
);

抱歉,我對 typeorm 不是很好,但這至少應該有效(或類似的方法)

你能試試? 占位符而不是@0 @1如下所示

    @Injectable()
    export class CustomerOutagesService {
      constructor(
        @InjectConnection('omsrecon')
        private connection: Connection,
      ) {}

      async getAll() {
        const data = await this.connection.manager
          .query('EXEC OMSRECON.GET_OMS_RECON_DATA ? ?', ['20220716', '20220717'])
          .then((res) => console.log(res))
          .catch((error) => console.log(error));
        console.log(data);
        return 'test';
      }
    }

根據 TypeORM 提供的 Oracle 查詢運行器對應的源代碼,它將查詢執行委托給底層 Oracle 庫實現:

const raw = await databaseConnection.execute(
  query,
  parameters || {},
  executionOptions,
)

事實證明,對於 Oracle TypeORM 使用oracledb

oracledb存儲庫中,您可以找到許多不同的使用示例 例如,考慮這個調用存儲過程的例子,尤其是這個代碼片段

// Invoke the PL/SQL stored procedure.
//
// The equivalent call with PL/SQL named parameter syntax is:
// `BEGIN
//    no_proc(p_in => :i, p_inout => :io, p_out => :o);
//  END;`


const result = await connection.execute(
  `BEGIN
     no_proc(:i, :io, :o);
   END;`,
   {
     i:  'Chris',  // Bind type is determined from the data.  Default direction is BIND_IN
     io: { val: 'Jones', dir: oracledb.BIND_INOUT },
     o:  { type: oracledb.NUMBER, dir: oracledb.BIND_OUT }
   }
);

它似乎與Query Builder在 TypeORM 中的工作方式一致。

請嘗試以下方法:

@Injectable()
export class CustomerOutagesService {
  constructor(
    @InjectConnection('omsrecon')
    private connection: Connection,
  ) {}

  async getAll() {
    const data = await this.connection.manager
      .query(
          `BEGIN
               OMSRECON.GET_OMS_RECON_DATA(:start_time, :end_time);
           END;`,
          {
              start_time: '20220716',
              end_time: '20220717'
          }
      )
      .then((res) => console.log(res))
      .catch((error) => console.log(error));
    console.log(data);
    return 'test';
  }
}

也許您需要處理DATE - 以防萬一,我會嘗試類似OMSRECON.GET_OMS_RECON_DATA(TO_DATE(:start_time, 'YYYYMMDD'), TO_DATE(:end_time, 'YYYYMMDD')); - 但我希望它有所幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM