Estou desenvolvendo uma rotina única de insert no banco onde passaríamos a tabela e uma temp-table com os valores para gravação. Ex.: Run pi-insert(Input 'cliente', Input-output table tt-cliente). Procedure pi-insert: Def input param piTabela as char no-undo. Def input param table for tt-default. /* => Probema: a temp-table tt-default teria que ser criada dinamicamente com as caractersticas da temp-table envianda*/ Create piTabela. Buffer-copy tt-default to piTabela. /* => Probema: O progress não permite a criação de um registro a partir do valor do parâmetro recebido nem o Buffer-copy da temp-table para a mesma*/ End Procedure. alguem já desenvolveu alguma rotina desse tipo?
Da uma olhada nessa função, acho que soluciona seu primeiro problema. Código: DEFINE VARIABLE tth AS HANDLE NO-UNDO. CREATE TEMP-TABLE tth. tth:ADD-FIELDS-FROM("Customer"). Não entendi o problema 2, se puder explicar melhor talvez possa ajudar.
Primeiramente obg pela resposta. Estamos trabalhando no conceito de aplicação distribuída, ou seja, no lado do usuário toda a manipulação dos dados é feita em temp-tables passando as mesmas por parâmetro para um programa externo que centraliza as manipulações no banco de dados. Todo processo é feito de forma estática, ou seja, criamos procedures internas de inserção, deleção, alteração e busca para cada tabela que precisamos dar manutenção. Ex.: exemplo1.p def temp-table tt-paciente like paciente field RowIdent as Rowid. Run SavePacienteRecord(input-output table tt-paciente, input 'novo', input tt-paciente.RowIdent). exemplo2.p PROCEDURE SavePacienteRecord : /*------------------------------------------------------------------------------ Purpose: Parameters: <none> Notes: ------------------------------------------------------------------------------*/ DEFINE INPUT-OUTPUT PARAMETER TABLE FOR tt-paciente. DEFINE INPUT PARAMETER pcMode AS CHARACTER NO-UNDO. DEFINE Input PARAMETER prRowIdent AS Rowid NO-UNDO. Find First tt-paciente Where tt-paciente.RowIdent = prRowIdent No-error. DO TRANSACTION: IF pcMode = "novo" THEN Do: Find Last Paciente Exclusive-lock No-error. If Avail Paciente Then Assign tt-paciente.codPaciente = Paciente.codPaciente + 1. Else Assign tt-paciente.codPaciente = 1. CREATE Paciente. End. ELSE FIND Paciente WHERE ROWID(Paciente) = tt-paciente.RowIdent EXCLUSIVE-LOCK NO-WAIT NO-ERROR. /* Do the following for both new and modified records */ IF AVAILABLE Paciente THEN BUFFER-COPY tt-paciente EXCEPT RowIdent TO Paciente. ELSE IF LOCKED (Paciente) THEN RETURN "Registro bloqueado. Tente mais tarde.". ELSE RETURN "Registro já foi deletado!". END. /* Transaction */ FIND CURRENT Paciente NO-LOCK. /* Remove the lock */ BUFFER-COPY Paciente TO tt-paciente. Assign tt-paciente.rowIdent = ROWID(Paciente). RETURN. END PROCEDURE. gostariamos de criar uma procedure única para tratar cada manipulação por exemplo criar uma parocedure que a partir dos parâmetros de "nome-da-table" e "um registro da temp-table" possa realizar inserção em qualquer tabela do banco dinamicamente. ou uma sugestão de como ser feito essa implementação no progress. /* Um problema que tenho para usar essa procedure dinamicamente é que passo como parametro uma temp-table com o registro para ser manipulada, sendo assim a temp-table que é esperada como parâmetro tem que conter as mesmas caracteristicas da passada por parametro. O Segundo é que se passar o nome da tabela por parametro exemplo SavePacienteRecord(input 'Paciente'). e recebe-la como um char def input param piTable as char no-undo. não consiguirei realizar comando de tabela no parâmetro ex.: find first piTable no-error. porque a table piTable não existe, mas sim o valor do parametro é o nome da tabela */
Eu usei nesse exemplo a tabela CLIENTE, se for alterar cuida de alterar o nome da Temp-Table também. Código: FUNCTION getNewID RETURNS DECIMAL ( INPUT pcNomeTabela AS CHARACTER ) : /*------------------------------------------------------------------------------ Purpose: Notes: ------------------------------------------------------------------------------*/ DEFINE VARIABLE hBuffer AS HANDLE NO-UNDO. CREATE BUFFER hBuffer FOR TABLE pcNomeTabela. hBuffer:FIND-LAST(). IF hBuffer:AVAILABLE THEN RETURN hBuffer:BUFFER-FIELD(1):BUFFER-VALUE + 1. RETURN 1. /* Function return value. */ END FUNCTION. /* Lado do Cliente , onde ocorre a criacao do registro */ DEFINE TEMP-TABLE tCliente NO-UNDO LIKE CLIENTE. DEFINE VARIABLE hBuffer AS HANDLE NO-UNDO. FIND LAST CLIENTE NO-LOCK NO-ERROR. CREATE tCliente. BUFFER-COPY CLIENTE TO tCliente. ASSIGN hBuffer = BUFFER tCliente:HANDLE. RUN 'ManipularRegistro' (INPUT 'Novo', INPUT hBuffer). IF RETURN-VALUE <> 'OK' THEN DO: MESSAGE RETURN-VALUE VIEW-AS ALERT-BOX ERROR BUTTONS OK. END. /* Processo executando no servidor */ PROCEDURE 'ManipularRegistro': DEFINE INPUT PARAMETER pcOperacao AS CHARACTER NO-UNDO. DEFINE INPUT PARAMETER phBuffer AS HANDLE NO-UNDO. DEFINE VARIABLE hTabela AS HANDLE NO-UNDO. DEFINE VARIABLE cNomeTab AS CHARACTER NO-UNDO. phBuffer:FIND-FIRST(). /* Consistencias Gerais */ IF NOT VALID-HANDLE(phBuffer) THEN DO: RETURN 'Condicao de Erro'. END. /* Aqui voces teriam que decidir um convencao para o nome da tabela parti do principio que o nome da temp-table tera que ser o nome da tabela com um T na frente (e.i.: Tabela: Fornecedor, Temp-Table tFornecedor */ ASSIGN cNomeTab = SUBSTRING(phBuffer:NAME, 2). CREATE BUFFER hTabela FOR TABLE cNomeTab. CASE pcOperacao: WHEN 'Novo' THEN DO: /* Consistencias da Operacao */ IF NOT phBuffer:AVAILABLE THEN DO: RETURN 'Condicao de Erro'. END. BLOCO_ATUALIZA: DO TRANSACTION ON ERROR UNDO BLOCO_ATUALIZA, RETURN 'Erro ao Criar Novo Registro.': hTabela:BUFFER-CREATE. hTabela:BUFFER-COPY(phBuffer, hTabela:BUFFER-FIELD(1):NAME). /* Aqui outra convencao, para pegar a chave do registro Decidi que o primerio campo da tabela sempre sera a chave do registro */ hTabela:BUFFER-FIELD(1):BUFFER-VALUE = getNewID(INPUT cNomeTab). hTabela:BUFFER-RELEASE. END. END. END. RETURN 'OK'. END PROCEDURE.
Porque você não passa a TEMP-TABLE inteira como parâmetro? Vou te mostrar um exemplo: 1. Primeiro você cria uma include (.i) com a definição padrão da TEMP-TABLE, tipo: DEF TEMP-TABLE teste FIELD nome AS CHAR FIELD idade AS INTEGER. 2. Tanto no programa Pai como no programa Filho, você chama essa include no DEFINITIONS: {pasta\definitions01.i} 3. No programa Pai (ex.: Pai.w ou .p) você executa o filho (filho.w ou .p) passando a temp-table já preenchida. RUN filho.w(INPUT TABLE teste). 4. Dentro do programa Filho, você coloca a chamada da include no definitions (conforme passo 2) e, logo após, cria a definição de parametro. DEF INPUT PARAMETER TABLE FOR teste. Obs.: Se você precisar mexer na temp-table atualizada após o programa filho usar, na definição de parâmetro você coloca INPUT-OUTPUT e no RUN também INPUT-OUTPUT. Pronto, agora você pode utilizar a tabela a vontade do outro lado, no programa filho. Espero ter ajudado. Att, Rafael