dbexpress driver does not support the tdbxtypes.unknown data type.Vendor error message(com parametros tipados)
Bom dia!!!
Vi em um outro post alguem com o mesmo problema, cujo a solução sugerida por de adicionar os datatypes aos parametros. Todos os parametros estão tipados, porém o erro persiste.
reduzi a query do insert para ficar mais fácil identificar o erro:
Parametros utilizados:
QueryProdutos.ParamByName('produto_codigo').AsString := edtCodigoProduto.Text;
QueryProdutos.ParamByName('produto_descricao').AsString := edtDescricao.Text;
QueryProdutos.ParamByName('produto_empresaid').AsInteger := 1;
QueryProdutos.ParamByName('produto_filialid').AsInteger := 1;
Query:
QueryProdutos.SQL.Clear;
QueryProdutos.SQL.Add('insert into produtos(' +
'produto_codigo,' +
'produto_descricao,' +
'produto_empresaid,'+
'produto_filialid,'+
'produto_um) values(:produto_codigo,:produto_descricao,:produto_empresaid,:produto_filialid,:produto_um);');
QueryProdutos.ExecSQL;
Fiz a tentativa também de, ao invés de usar os parametros, utilizar o conteudo dos edits.. porém não conseguir concatenar as strings, pois tanto o Quotestr, #29 ficaram com duas aspas simples ao invés de uma. já a opção de 3 aspas não funcionou tambem. Não sei se isso pode ser algo que eu precise configurar na versão 11 do delphi
Espero que consigam me ajudar!!
Vi em um outro post alguem com o mesmo problema, cujo a solução sugerida por de adicionar os datatypes aos parametros. Todos os parametros estão tipados, porém o erro persiste.
reduzi a query do insert para ficar mais fácil identificar o erro:
Parametros utilizados:
QueryProdutos.ParamByName('produto_codigo').AsString := edtCodigoProduto.Text;
QueryProdutos.ParamByName('produto_descricao').AsString := edtDescricao.Text;
QueryProdutos.ParamByName('produto_empresaid').AsInteger := 1;
QueryProdutos.ParamByName('produto_filialid').AsInteger := 1;
Query:
QueryProdutos.SQL.Clear;
QueryProdutos.SQL.Add('insert into produtos(' +
'produto_codigo,' +
'produto_descricao,' +
'produto_empresaid,'+
'produto_filialid,'+
'produto_um) values(:produto_codigo,:produto_descricao,:produto_empresaid,:produto_filialid,:produto_um);');
QueryProdutos.ExecSQL;
Fiz a tentativa também de, ao invés de usar os parametros, utilizar o conteudo dos edits.. porém não conseguir concatenar as strings, pois tanto o Quotestr, #29 ficaram com duas aspas simples ao invés de uma. já a opção de 3 aspas não funcionou tambem. Não sei se isso pode ser algo que eu precise configurar na versão 11 do delphi
Espero que consigam me ajudar!!
Andre Moreira
Curtidas 0
Respostas
Arthur Heinrich
13/07/2023
Não sei se entendi corretamente o seu problema, mas vejo algumas coisas no seu código, que entendo que podem dar problema. Também tem a dúvida sobre a função QuotedStr().
A primeira coisa que reparei é que você terminou o comando SQL com ";".
Tenho a impressão de que, embora este caractere seja corretamente interpretado pelas ferramentas do banco, ao colocar o comando em um componente TQuery ou suas variações, o terminador ";" não deve ser utilizado, pois pode acusar erro de sintaxe.
O outro problema é que, no seu código, você executa diretamente:
QueryProdutos.SQL.Add('insert ...');
QueryProdutos.ExecSQL;
Em uma query que não utiliza paraâmetros, este é um procedimento comum. Porém, no seu caso, você utilizou bind variables e, antes de executar a query, precisa informar o valor de cada uma delas.
Uma vez que você não informa os parâmetros antes de executar, o componente não sabe como enviar os parâmetros e, esta indefinição, deve estar sendo interpretada como "parâmetro com tipo indefinido/inválido.
Quanto à função QuotedStr(), ela tem, por objetivo, colocar um texto entre aspas. Porém, como o próprio texto pode conter aspas, ele precisa duplicar cada aspas, para que seja interpretada como parte do texto e não como fim de texto.
Quando queremos fazer um texto contendo a aspas simples, fazemos:
s := 'it''s OK!'; Duas aspas simples que serão interpretadas como uma: it's OK!
Se utilizamos:
s := 'it's OK!'; Utilizando uma aspas simples, o compilador pensa que a string termina no 'it' e acusa erro de sintaxe.
A função QuotedStr() vem simplificar isso.
QuotedStr('teste') -> 'teste'
s := 'it''s OK!'; // s recebe o texto: it's OK!
QuotedStr(s) -> 'it''s OK!' // retorna o texto entre aspas simples, contendo todas as aspas contidas no texto duplicadas.
Você utilizaria:
QueryProdutos.SQL.Add('insert into produtos values('+QuotedStr(CodProduto)+','+QuotedStr(DescProduto)...);
A query ficaria como:
'insert into produtos values('123','Produto 123'...);
Isto ajuda a evitar o problema de SQL Injection, onde o usuário quebra a sua query informando um texto contendo as aspas: parâmetro = ' or 1=1 or '
A primeira coisa que reparei é que você terminou o comando SQL com ";".
Tenho a impressão de que, embora este caractere seja corretamente interpretado pelas ferramentas do banco, ao colocar o comando em um componente TQuery ou suas variações, o terminador ";" não deve ser utilizado, pois pode acusar erro de sintaxe.
O outro problema é que, no seu código, você executa diretamente:
QueryProdutos.SQL.Add('insert ...');
QueryProdutos.ExecSQL;
Em uma query que não utiliza paraâmetros, este é um procedimento comum. Porém, no seu caso, você utilizou bind variables e, antes de executar a query, precisa informar o valor de cada uma delas.
// Limpa a query QueryProdutos.SQL.Clear; // Informa o comando utilizando bind variables QueryProdutos.SQL.Add('insert into produtos(' + 'produto_codigo,' + 'produto_descricao,' + 'produto_empresaid,'+ 'produto_filialid,'+ 'produto_um) values(:produto_codigo,:produto_descricao,:produto_empresaid,:produto_filialid,:produto_um);'); // Pode setar os parâmetros por posição: QueryProdutos.Params[0].AsInteger := 123; // Código do produto QueryProdutos.Params[1].AsString := 'Produto 123'; // Descrição do produto ... Ou, pode informar os parâmetros através do nome QueryProdutos.ParamByName('produto_codigo').AsInteger := 123; QueryProdutos.ParamByName('produto_descricao').AsString := 'Produto 123'; ... // Por fim, executa o comando QueryProdutos.ExecSQL;
Uma vez que você não informa os parâmetros antes de executar, o componente não sabe como enviar os parâmetros e, esta indefinição, deve estar sendo interpretada como "parâmetro com tipo indefinido/inválido.
Quanto à função QuotedStr(), ela tem, por objetivo, colocar um texto entre aspas. Porém, como o próprio texto pode conter aspas, ele precisa duplicar cada aspas, para que seja interpretada como parte do texto e não como fim de texto.
Quando queremos fazer um texto contendo a aspas simples, fazemos:
s := 'it''s OK!'; Duas aspas simples que serão interpretadas como uma: it's OK!
Se utilizamos:
s := 'it's OK!'; Utilizando uma aspas simples, o compilador pensa que a string termina no 'it' e acusa erro de sintaxe.
A função QuotedStr() vem simplificar isso.
QuotedStr('teste') -> 'teste'
s := 'it''s OK!'; // s recebe o texto: it's OK!
QuotedStr(s) -> 'it''s OK!' // retorna o texto entre aspas simples, contendo todas as aspas contidas no texto duplicadas.
Você utilizaria:
QueryProdutos.SQL.Add('insert into produtos values('+QuotedStr(CodProduto)+','+QuotedStr(DescProduto)...);
A query ficaria como:
'insert into produtos values('123','Produto 123'...);
Isto ajuda a evitar o problema de SQL Injection, onde o usuário quebra a sua query informando um texto contendo as aspas: parâmetro = ' or 1=1 or '
GOSTEI 0
Andre Moreira
13/07/2023
Bom dia!!!!!
Descobri o problema aqui... vendo como referencia tua resposta!!!
1 - Removi o ";" do sql
2 - adicionei a atribuição dos valores dos parametros após a montagem do SQL (eu já tinha colocado os valores, porém antes de começar o "add")
desta forma funcionou
Sobre o Quotestr... sim!!!! estou usando desta forma, porém fica assim:
'insert into produtos values(''123'',''Produto 123''...);
Agora o porque..... não faço idéia
mas.. vou usar como parametro mesmo já que funcionou!!!
Obrigado pela força!!!
Grande abraço!!!
Descobri o problema aqui... vendo como referencia tua resposta!!!
1 - Removi o ";" do sql
2 - adicionei a atribuição dos valores dos parametros após a montagem do SQL (eu já tinha colocado os valores, porém antes de começar o "add")
desta forma funcionou
Sobre o Quotestr... sim!!!! estou usando desta forma, porém fica assim:
'insert into produtos values(''123'',''Produto 123''...);
Agora o porque..... não faço idéia
mas.. vou usar como parametro mesmo já que funcionou!!!
Obrigado pela força!!!
Grande abraço!!!
GOSTEI 0