Oracle
 sql >> Base de Dados >  >> RDS >> Oracle

Erro de tempo de execução:-2147217887(80040e21) O sistema não pode encontrar um texto de mensagem para o número de mensagem 0x80040e21 no arquivo de mensagem para OraOLEDB


Com tantos parâmetros, o problema pode ser qualquer um item incluindo tipo de dados incompatíveis, comprimento de dados, etc. Aqui é onde a técnica conhecida como depuração deve ser exercitada.

  1. Verifique cuidadosamente os tipos de dados da tabela (T_SAP_ZSSTABL_NEW ). A Oracle pode ter tipos de dados que não são imediatamente traduzíveis por tipos ADO como BLOB , CLOB , BFILE , tipos numéricos de alta precisão, tipos máximos de caracteres ou tipos de extensão (XML, mídia etc.).

  2. Tente estender os comprimentos dos dados (ou deixe em branco na atribuição de parâmetros):
    Set MyParameter = cmd.CreateParameter("MATNR", adVarChar, adParamInput, 100, POSNR)
    
    Set MyParameter = cmd.CreateParameter("MATNR", adVarChar, adParamInput, , POSNR)
    

    Se necessário, verifique os comprimentos variáveis ​​com Len() do VBA para gerar um aviso ao usuário antes de anexar parâmetros.

  3. Tente executar o SELECT versão da consulta com os mesmos parâmetros para retornar uma única linha de resultados. Se ocorrer o mesmo erro, comece com o primeiro parâmetro e adicione um segundo ou lote de 10 sequencialmente para isolar o item problemático.
    SELECT ? AS TSZ_CHARG_PARAM, ? AS TSZ_MATNR_PARAM, ? AS TSZ_MAKTX_PARAM,
           ...
    FROM T_SAP_ZSSTABL_NEW
    WHERE TSZ_VBELN = ? AND TSZ_POSNR = ?
    

  4. Refatore o código para consistência, pois você pode ter perdido um ou desalinhado, o que pode ocorrer com muitas linhas repetitivas. Sempre aponte para o código DRY (Don't Repeat Yourself). Uma opção é usar um dicionário com pares de chave/valor em vez de mais de 160 variáveis ​​ou intervalos nomeados:
    Dim key As Variant
    Dim paramDict As Object
    Set paramDict = CreateObject("Scripting.Dictionary")
    
    For ...
        paramDict.Add "KeyX", "ValueX"
    Next ...
    
    ...
    
    With cmd
      .ActiveConnection = myOracleConn
      .CommandText = strSQL
      .CommandType = adCmdText
    
      For Each key In  paramDict.Keys
         .Parameters.Append .CreateParameter(key, adVarChar, adParamInput, , paramDict(key))
      Next key
    
      .Execute
    End With
    

    Se você tiver tipos mistos, tente criar dicionários diferentes para cada tipo e itere-os em sequência para anexar parâmetros. E ajuste UPDATE com todos os mesmos tipos próximos uns dos outros. Recupere UPDATE não precisa seguir a ordem das colunas na definição da tabela.

  5. Se possível (ou solução de longo prazo), considere redesenhar a tabela de formato amplo de TSZ colunas em uma forma normalizada de formato longo.
    ID   POSNR   VBELN   Indicator   Value
     #     XXX     XXX       CHARG     XXX
     #     XXX     XXX       MATNR     XXX
     #     XXX     XXX       MAKTX     XXX
    ...
    

    Embora isso adicione 167 linhas para cada identificador exclusivo, no design do banco de dados, as linhas são muito mais baratas do que as colunas e, portanto, as consultas serão mais fáceis, o armazenamento de dados mais escalável e a manutenção mais eficiente. Por exemplo, uma nova métrica não precisa de uma nova coluna definida com todas as meta-informações, mas simplesmente uma nova linha. E com o PIVOT da Oracle você pode facilmente renderizar novamente o formato amplo.

Em suma, não há uma maneira única e clara de depurar um erro de tempo de execução como esse, proveniente de uma extensão de API, como conexão de banco de dados. A sintaxe SQL ou a referência de objeto VBA podem ser facilmente tratadas, mas problemas específicos de dados exigem uma análise criativa do processo geral.