Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Conexión con bases de datos (https://www.clubdelphi.com/foros/forumdisplay.php?f=2)
-   -   Error en sentencia con comillas dobles (https://www.clubdelphi.com/foros/showthread.php?t=68475)

bismarck_sierra 16-06-2010 06:06:35

Error en sentencia con comillas dobles
 
Que tal

Tengo esta sentencia SQL que se ejecuta normal en cualquier cliente para firebird (IBOConsole, IBExpert), pero en mi aplicación me da un error "unexpected end of command"

Código SQL [-]
UPDATE articulos SET descripcion = 'ANGULO 2.8 MM X 1" LIGERO', 
descripcion_corta = 'ANGULO 2.8 MM X 1"', etiqueta = 'Angulo 2.8 mm x 1"', 
categoria = 2, departamento = null, clase = null, impuesto = 1, 
es_juego = 'N', costo_automatico = 'S', precio_automatico = 'N', 
se_vende = 'S', es_gasto = 'N', no_inventariable = 'N', agranel = 'S', 
bascula = 'N', tiempo_elaboracion = 0, tiene_numero_serie = 'N', 
tiene_lote = 'N', tiene_caducidad = 'N', generar_boletos = 'N', 
cambiar_precio = 'N', estatus = 'A', notas = '', fecha_ult_cambio = '06/12/2010 08:43:53', 
ultimo_costo = 86.77, tienda_en_linea = 'N', peso = 6, largo = 6, 
ancho = 0, alto = 0, fecha_importacion = '06/12/2010 08:44:29' WHERE clave = 37

Para armar esta sentencia utilizo QuotedStr(), y la anterior sentencia la tomé en tiempo de ejecución, es decir, así es como la manda a firebird.

El error me lo marca en el primer apostrofe de la fecha_ult_cambio

El problema lo da al poner las comillas dobles que van en las descripciones del producto, pero son datos del usuario, no se pueden quitar.

Utilizo Delphi 7 con dbexpress y firebird 2.1.2

¿Que podra ser?, ¿problemas de compatibilidad de dbexpress que trae Delphi 7?, ¿el juego de caracteres definido en la base de datos?

Gracias de antemano

Saludos
Bismarck

Casimiro Notevi 16-06-2010 11:16:21

¿Puedes poner el código en delphi?

bismarck_sierra 16-06-2010 14:01:45

Claro que si

Código Delphi [-]
        sSentencia:= 'UPDATE articulos SET descripcion = ' + QuotedStr(Datos.sDescripcion) +
                 ', descripcion_corta = ' + QuotedStr(Datos.sDescripcionCorta) +
                 ', etiqueta = ' + QuotedStr(Datos.sEtiqueta) +
                 ', categoria = ' + sClaveCategoria +
                 ', departamento = ' + sClaveDepto +
                 ', clase = ' + sClaveClase +
                 ', impuesto = ' + IntToStr(Datos.iClaveImpuesto) +
                 ', es_juego = ' + QuotedStr(Datos.sEsJuego) +
                 ', costo_automatico = ' + QuotedStr(Datos.sCostoAutomatico) +
                 ', precio_automatico = ' + QuotedStr(Datos.sPrecioAutomatico) +
                 ', se_vende = ' + QuotedStr(Datos.sSeVende) +
                 ', es_gasto = ' + QuotedStr(Datos.sEsGasto) +
                 ', no_inventariable = ' + QuotedStr(Datos.sNoInventariable) +
                 ', agranel = ' + QuotedStr(Datos.sAgraNel) +
                 ', bascula = ' + QuotedStr(Datos.sBascula) +
                 ', tiempo_elaboracion = ' + IntToStr(Datos.iTiempoElaboracion) +
                 ', tiene_numero_serie = ' + QuotedStr(Datos.sTieneNumeroSerie) +
                 ', tiene_lote = ' + QuotedStr(Datos.sTieneLote) +
                 ', tiene_caducidad = ' + QuotedStr(Datos.sTieneCaducidad) +
                 ', generar_boletos = ' + QuotedStr(Datos.sGenerarBoletos) +
                 ', cambiar_precio = ' + QuotedStr(Datos.sCambiarPrecio) +
                 ', estatus = ' + QuotedStr(Datos.sEstatus) +
                 ', notas = ' + QuotedStr(Datos.sNotas) +
                 ', fecha_ult_cambio = ' + QuotedStr(FormatDateTime(FECHA_HORA_DBMS, dteFechaMov)) +
                 ', ultimo_costo = ' + FloatToStr(Datos.rCosto) +
                 ', tienda_en_linea = ' + QuotedStr(Datos.sTiendaEnLinea) +
                 ', peso = ' + FloatToStr(Datos.rPeso) +
                 ', largo = ' + FloatToStr(Datos.rLargo) +
                 ', ancho = ' + FloatToStr(Datos.rAncho) +
                 ', alto = ' + FloatToStr(Datos.rAlto) +
                 ', fecha_importacion = ' + QuotedStr(sFechaImporta) +
                 ' WHERE clave = ' + IntToStr(Datos.iClave);

qryConsulta:= TSQLQuery.Create(nil);
qryConsulta.SQLConnection:= FBaseDato;
qryConsulta.SQL.Clear;
qryConsulta.SQL.Text:= sSentencia;
qryConsulta.ExecSQL;

Como no le he econtrado por donde es el error intenté cambiar la asignación de la sentencia a qryConsulta con los metodos qryConsulta.Add, qryConsulta.Append

Saludos
Bismarck

marcoszorrilla 16-06-2010 15:00:44

También puedes probar a poner justo antes de ejectur la consulta:

Código Delphi [-]
ShowMessage(qryConsulta.SQL.Text);

De esta manera verás si te construye la sentencia SQL como tu esperas o ya de hecho encuentras algún fallo.

Un Saludo.

Casimiro Notevi 16-06-2010 15:05:31

A simple vista no se ve nada mal, se supone que ese campo es del tipo timestamp, no?

bismarck_sierra 16-06-2010 15:41:38

Gracias Marcos por tu comentario, la primera consulta que puse en el post, es como se arma antes de mandar llamar a ExecSQL.

Las pruebas que he realizado obtengo resultados extraños, si agrego una comillas dobles dentro del valor de otro campo, por ejemplo:

Código Delphi [-]
, notas = '2.8 1" '

funciona bien, es decir, descripcion, descripcion_corta, etiqueta y notas tienen una comilla doble, no importa en que campos tenga comillas dobles en pares, todo marcha bien, pero si acumulo "comillas dobles" acumulando un número impar en diferentes campos ya no funciona.

Nunca me habia pasado eso, trataré con otras cosas, tal vez sea porque compilo Delphi 7 en Windows 7, probaré con Windows XP.

Saludos

Bismarck

Casimiro Notevi 16-06-2010 17:35:23

Con la explicación que has dado ahora me ha resultado más fácil, el problema es este:
'ANGULO 2.8 MM X 1" LIGERO',

las comillas de las pulgadas

roman 16-06-2010 21:32:59

Cita:

Empezado por Casimiro Notevi (Mensaje 367447)
Con la explicación que has dado ahora me ha resultado más fácil, el problema es este:
'ANGULO 2.8 MM X 1" LIGERO',

las comillas de las pulgadas

Pero, ¿en qué consiste el problema? Según entiendo, el error lo dal el motor de firebird y, sin embargo, el compañero bismark_sierra comentó al principio que la sentencia no le causa problemas si la ejecuta en el IBExpert. Da la impresión de que el contenido de qryConsulta.SQL.Text no es exactamente el mismo que el que llega al motor.

// Saludos

marcoszorrilla 16-06-2010 21:45:28

Por eso decía yo lo de utilizar ShowMessage, para ver como queda realmente la sentencia que se va a enviar al motor y de esta manera al menos yo suelo detectar caracteres indeseados o composición incorrecta del SQL.

Quizás utilizando parámetros y AsString en vez de QuotedSqr llegue a funcionar la sentencia,

Yo ejecutaría la sentencia solamente con la parte que se cree da el error y luego creo que con un par de ensayos se arreglaría el problema.

Un Saludo.

Casimiro Notevi 16-06-2010 22:02:09

Cita:

Empezado por roman (Mensaje 367471)
Pero, ¿en qué consiste el problema? Según entiendo, el error lo dal el motor de firebird y, sin embargo, el compañero bismark_sierra comentó al principio que la sentencia no le causa problemas si la ejecuta en el IBExpert. Da la impresión de que el contenido de qryConsulta.SQL.Text no es exactamente el mismo que el que llega al motor.
// Saludos

Claro, porque la sentencia que está usando en el ibexpert no es la que está generando en delphi.

Y el problema es ese, que las comillas de pulgadas está deformando la sentencia. Si se hace lo que comenta marcos se vería realmente la sentencia que se está creando. O deteniendo el programa con un breakpoint y mirando el contenido del query.sql.text, por supuesto.

roman 16-06-2010 22:31:16

Cita:

Empezado por Casimiro Notevi (Mensaje 367482)
Claro, porque la sentencia que está usando en el ibexpert no es la que está generando en delphi.

¿Cómo sabes esto? El compañero ya mencionó que

Cita:

Empezado por bismark_sierra
Gracias Marcos por tu comentario, la primera consulta que puse en el post, es como se arma antes de mandar llamar a ExecSQL.

Cita:

Empezado por Casimiro Notevi (Mensaje 367482)
Y el problema es ese, que las comillas de pulgadas está deformando la sentencia.

¿De qué manera deforma la sentencia? Al menos en MySQL, una sentencia así es correcta ya que el valor completo del campo está encerrado entre comillas sencillas. Y si tal sintaxis no fuese correcta en Firebird entonces habría encontrado el problema desde el IBExpert.

// Saludos

Casimiro Notevi 16-06-2010 22:41:57

El problema no es firebird, es delphi.

Si con el ibexpert, por ejemplo, ejecuto un:

Código SQL [-]
insert into tbArticulos values (2222,'rueda de 20" de diámetro')

Lo hace perfectamente. Pero si desde delphi vas componiendo la sentencia no lo hace bien, se confunde con las comillas. Puede que usando algo así lo haga bien:
Código:

'rueda de 20'#34' de diámetro'
O bien:
Código:

'rueda de 20'+#34+' de diámetro'

roman 17-06-2010 18:34:32

Cita:

Empezado por Casimiro Notevi (Mensaje 367490)
Pero si desde delphi vas componiendo la sentencia no lo hace bien, se confunde con las comillas.

No entiendo a qué te refieres con que se confunde con las comillas. ¿De qué modo se confunde?

Si yo pongo:

Código Delphi [-]
var
  sSentencia: String;

begin
  sSentencia := 'etiqueta = ' + QuotedStr(Edit1.Text);
  ShowMessage(sSentencia);
end;

donde Edit1 contiene el texto

rueda de 20" de diámetro

el ShowMessage muestra

'rueda de 20" de diámetro'

El compilador no se queja y la sentencia queda igual que como se pondría directamente en el IBExpert.

A lo que voy es que, al menos a mi, no me parece tan claro dónde radica el problema. No sé si los componentes en particular que use hacen algún tipo de escape de comillas al momento de enviar la consulta al servidor.

// Saludos

marcoszorrilla 17-06-2010 18:40:17

Yo creo que el problema viene del componente utilizado en este caso de las Ib que al encontrar las dobles comillas no las interpreta bien.

Por eso yo decía mostrar el SQL con un ShowMessage porque aunque pueda parecer evidente que lo escrito está bien al mostrarlo con el ShowMessage vemos lo que se le va a enviar al motor y a veces, doy fe no coincide.

Un Saludo.

bismarck_sierra 22-06-2010 23:55:50

Solución muy cara
 
Que tal

Después de tanto probar, opté por bajar el trial de Delphi 2010 y probar el mismo código con algunas adaptaciones en algunos componentes de terceros para que compilara correctamente y funcionó.

Así que algún problema tiene Delphi 7 con las comillas dobles dentro de las cadenas.

Aún así buscaré otra opción ya que Delphi 2010 "Enterprise" que es el que tiene el dbExpress para Firebird es una solución muy cara para resolver el problema de las comillas.

Gracias a todos

Saludos
Bismarck

Casimiro Notevi 23-06-2010 01:23:29

También puedes usarlo así, sin problemas:
Código:

query.close;
query.sql.text := 'insert into articulos values( :codigo, :descripcion, :precio)';
query.parambyname('codigo').asinteger := 100;
query.parambyname('descripcion').asstring := 'Tele de 60" cúbicas';
query.parambyname('precio').asfloat := 25;
query.execquery;

"Toda la vida" hemos usados comillas dobles y no existía delphi 2010 :)

bismarck_sierra 23-06-2010 03:15:39

Intenté con parámetros y me daba el mismo resultado, hasta antes de este problema yo también utilizaba "toda la vida" las comillas dobles sin problemas.

En este programa tengo un modulo llamado "Consultas SQL" donde puedo poner sentencias SQL directas sin "armarlas" y también me marcaba el mismo error.

En este módulo me puse a jugar con la sentencia UPDATE problemática, quitandole y poniéndole comillas a varios campos con resultados extraños. Si quitaba un campo de la sentencia tipo String o timestamp funcionaba, si agregaba una comilla doble a cualquier campo funcionaba, pero no le encontré la lógica.

Y lo más extraño es que sin hacerle nada al código, sólo actualizando al dbexpress de Delphi 2010 funcionó.

Seguiré probando hasta encontrar cual es el problema

Saludos
Bismarck

Saludos

Casimiro Notevi 23-06-2010 13:10:16

Cita:

Empezado por bismarck_sierra (Mensaje 368132)
Intenté con parámetros y me daba el mismo resultado, hasta antes de este problema yo también utilizaba "toda la vida" las comillas dobles sin problemas. [..]

Entonces, ¿qué ha cambiado para que ahora tengas ese problema?


La franja horaria es GMT +2. Ahora son las 10:09:33.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi