una brutalidad?

25/02/2004 - 19:45 por Emerson | Informe spam
quise hacer esta query, por ignorancia, porque al estudia EXISTS, me di
cuenta que lo que estoy haciendo es una brutalidad.

cómo lo debo hacer, si en la misma query quiero comprobar si existen los
valores, de no ser así ingresarlos.

gracias.

Emerson

IF NOT EXISTS (SELECT id_producto FROM PFP WHERE id_producto = 10 AND
id_forma_pago = 4)
(INSERT INTO PFP(id_producto, id_forma_pago) VALUES (10, 4))

Preguntas similare

Leer las respuestas

#11 Emerson
27/02/2004 - 15:16 | Informe spam
es discusión de mayores, aquí sólo es mi deber aprender y agradecer.

EG

"Javier Loria" escribió en el mensaje
news:uS5eyEU$
Hola Miguel:
Yo creo que me estas provocando para que tengamos una discusion al


mejor
estilo de la de identity ;). En todo caso siempre he sido muy tolerante a
este tipo de diferencias y es un placer intercambiar opiniones con un gran
conocedor de SQL, y aun cuando no tengas razon me obligas a cuestionar mi
"librito".
En realidad si revisas mi sugerencia veras que los IF EXISTS(SELECT)
estan ANTES de la TRANSACCION, por ende no estan generando BLOQUEOS!.
De hecho este patron que genera menos bloqueos que el de tratar y
probar, porque se deshace del 99% de los errores que ocurren ANTES DE
INICIAR la Transaccion. Ejemplo: Si voy a realizar una serie de


modificacion
(INSERT, DELETE, UPDATE) que puede fallar, (por PK, FK, CHECK, etc).


reviso
antes de iniciar el proceso que se cumplan las reglas y si se cumplen


luego
trato de ejecutarlos. Solo en el caso que algun otro usuario haya


cambiando
las filas en ese momento se rompera la regla pero este sera unicamente el


1%
de las veces. Claro es posible que fallen por eso necesito siempre el: IF
@@Error. Pero solo fallan si se produce alguna modificacion "simultanea".
El patron pruebe si falla, tiene el problema que inicia la


transaccion,
realiza modificaciones (bloqueando los registros involucrados), disparando
los triggers, y grabando en la bitacora del Log, para luego si hay un


error
en la ultima actualizacion, hacer rollback de todo!!!. Esto es mas lento y
con mayor cantidad de bloqueos que el patron por mi posteado.
Una ventaja adicional del patron posteado es que permite personalizar
los errores.
Claro no todo es color de rosa en este esquema que sugeri, tiene


algunos
problemas, principalmente:
a) Obligar al desarrollador ha escribir mas codigo (haciendo mas lento
el proceso de generacion de software),
b) Mayor costo de manenimiento (tengo que cambiar el CHECK y cambiar


el
Procedimiento Almacenado).
Esa es mi opinion, pero voy a ver si escribo alguna prueba de


desempeno.
Saludos,


Javier Loria
Costa Rica
Se aprecia la inclusion de DDL (CREATE, INSERTS, etc.)
que pueda ser copiado y pegado al Query Analizer.
La version de SQL y Service Pack tambien ayuda.

Miguel Egea escribio:
> A mi no me parece esa forma del todo correcta porque los patrones
> SElect-insert tienen varios problemas
> el primero es que si el nivel de aislamiento es bajo, nada garantiza
> que dos puestos no ejecuten las sentencias justo en el orden en que
> te de error por clave duplicada de todas formas. El segundo es que si
> por el contrario pones un nivel de aislamiento alto, tienes muchas
> posibilidades de obtener un deadlock en los mismos casos. Por eso me
> decanto por recuperarme (en este caso) del error de pk.
>
>
>
> Miguel Egea
> Microsoft SQL-SERVER MVP
> Brigada Anti-Cursores
> "Juan Carlos Leguizamón"
> escribió en el mensaje news:eNXYXXK$
>> Totalmente de acuerdo, ya decia yo que no podia estar tan equivocado
>> en mis creencias ...
>>
>> "Javier Loria" escribió en el mensaje
>> news:eefXfbJ$
>>> Hola:
>>> Pues a mi me parece que NO es una brutalidad y es perfectamente
>>> valido el patron de INSERCION:
>>> => >>> IF NOT EXISTS (...)
>>> BEGIN
>>> INSERT .
>>> END
>>> => >>> Yo particularmente soy mas amigo de:
>>> => >>> IF EXISTS(...)
>>> BEGIN
>>> RAISERROR(...)
>>> ROLLBACK
>>> END
>>> IF EXISTS(..)
>>> BEGING
>>> RAISERROR(...)
>>> ROLLBACK
>>> END
>>>
>>> BEGIN TRAN
>>> INSERT ...
>>> IF @@ERROR <> THEN
>>> INSERT ...
>>> IF @@ERROR <> THEN
>>> INSERT ...
>>> COMMIT
>>> => >>> Pero me parece PERFECTAMENTE VALIDO el codigo que escribes.
>>> Saludos,
>>>
>>>
>>> Javier Loria
>>> Costa Rica
>>> Se aprecia la inclusion de DDL (CREATE, INSERTS, etc.)
>>> que pueda ser copiado y pegado al Query Analizer.
>>> La version de SQL y Service Pack tambien ayuda.
>>> Emerson <emerson_sacar_arroba_leshalles.cl> escribio:
>>>> ya que estaba ocupando EXISTS para validar los datos en una tabla y
>>>> luego insertandoles, y me percate que EXISTS es para otra cosa, es
>>>> más similar al IN...
>>>>
>>>> EG
>>>>
>>>>
>>>> "Juan Carlos Leguizamón"
>>>> escribió en el mensaje
>>>> news:#wmNp4H$
>>>>> Hola, esta vez no entendí. ¿porque esto es una brutalidad?
>>>>>
>>>>> "Emerson" <emerson_sacar_arroba_leshalles.cl> escribió en el
>>>>> mensaje news:%23F8xfC$%
>>>>>> quise hacer esta query, por ignorancia, porque al estudia EXISTS,
>>>>>> me di cuenta que lo que estoy haciendo es una brutalidad.
>>>>>>
>>>>>> cómo lo debo hacer, si en la misma query quiero comprobar si
>>>>>> existen los valores, de no ser así ingresarlos.
>>>>>>
>>>>>> gracias.
>>>>>>
>>>>>> Emerson
>>>>>>
>>>>>> IF NOT EXISTS (SELECT id_producto FROM PFP WHERE id_producto > >>>>>> 10 AND id_forma_pago = 4)
>>>>>> (INSERT INTO PFP(id_producto, id_forma_pago) VALUES (10, 4))


Respuesta Responder a este mensaje
#12 Javier Loria
27/02/2004 - 15:51 | Informe spam
Hola Miguel:
Yo creo que me estas provocando para que tengamos una discusion al mejor
estilo de la de identity ;). En todo caso siempre he sido muy tolerante a
este tipo de diferencias y es un placer intercambiar opiniones con un gran
conocedor de SQL, y aun cuando no tengas razon me obligas a cuestionar mi
"librito".
En realidad si revisas mi sugerencia veras que los IF EXISTS(SELECT)
estan ANTES de la TRANSACCION, por ende no estan generando BLOQUEOS!.
De hecho este patron que genera menos bloqueos que el de tratar y
probar, porque se deshace del 99% de los errores que ocurren ANTES DE
INICIAR la Transaccion. Ejemplo: Si voy a realizar una serie de modificacion
(INSERT, DELETE, UPDATE) que puede fallar, (por PK, FK, CHECK, etc). reviso
antes de iniciar el proceso que se cumplan las reglas y si se cumplen luego
trato de ejecutarlos. Solo en el caso que algun otro usuario haya cambiando
las filas en ese momento se rompera la regla pero este sera unicamente el 1%
de las veces. Claro es posible que fallen por eso necesito siempre el: IF
@@Error. Pero solo fallan si se produce alguna modificacion "simultanea".
El patron pruebe si falla, tiene el problema que inicia la transaccion,
realiza modificaciones (bloqueando los registros involucrados), disparando
los triggers, y grabando en la bitacora del Log, para luego si hay un error
en la ultima actualizacion, hacer rollback de todo!!!. Esto es mas lento y
con mayor cantidad de bloqueos que el patron por mi posteado.
Una ventaja adicional del patron posteado es que permite personalizar
los errores.
Claro no todo es color de rosa en este esquema que sugeri, tiene algunos
problemas, principalmente:
a) Obligar al desarrollador ha escribir mas codigo (haciendo mas lento
el proceso de generacion de software),
b) Mayor costo de manenimiento (tengo que cambiar el CHECK y cambiar el
Procedimiento Almacenado).
Esa es mi opinion, pero voy a ver si escribo alguna prueba de desempeno.
Saludos,


Javier Loria
Costa Rica
Se aprecia la inclusion de DDL (CREATE, INSERTS, etc.)
que pueda ser copiado y pegado al Query Analizer.
La version de SQL y Service Pack tambien ayuda.

Miguel Egea escribio:
A mi no me parece esa forma del todo correcta porque los patrones
SElect-insert tienen varios problemas
el primero es que si el nivel de aislamiento es bajo, nada garantiza
que dos puestos no ejecuten las sentencias justo en el orden en que
te de error por clave duplicada de todas formas. El segundo es que si
por el contrario pones un nivel de aislamiento alto, tienes muchas
posibilidades de obtener un deadlock en los mismos casos. Por eso me
decanto por recuperarme (en este caso) del error de pk.



Miguel Egea
Microsoft SQL-SERVER MVP
Brigada Anti-Cursores
"Juan Carlos Leguizamón"
escribió en el mensaje news:eNXYXXK$
Totalmente de acuerdo, ya decia yo que no podia estar tan equivocado
en mis creencias ...

"Javier Loria" escribió en el mensaje
news:eefXfbJ$
Hola:
Pues a mi me parece que NO es una brutalidad y es perfectamente
valido el patron de INSERCION:
=>>> IF NOT EXISTS (...)
BEGIN
INSERT .
END
=>>> Yo particularmente soy mas amigo de:
=>>> IF EXISTS(...)
BEGIN
RAISERROR(...)
ROLLBACK
END
IF EXISTS(..)
BEGING
RAISERROR(...)
ROLLBACK
END

BEGIN TRAN
INSERT ...
IF @@ERROR <> THEN
INSERT ...
IF @@ERROR <> THEN
INSERT ...
COMMIT
=>>> Pero me parece PERFECTAMENTE VALIDO el codigo que escribes.
Saludos,


Javier Loria
Costa Rica
Se aprecia la inclusion de DDL (CREATE, INSERTS, etc.)
que pueda ser copiado y pegado al Query Analizer.
La version de SQL y Service Pack tambien ayuda.
Emerson <emerson_sacar_arroba_leshalles.cl> escribio:
ya que estaba ocupando EXISTS para validar los datos en una tabla y
luego insertandoles, y me percate que EXISTS es para otra cosa, es
más similar al IN...

EG


"Juan Carlos Leguizamón"
escribió en el mensaje
news:#wmNp4H$
Hola, esta vez no entendí. ¿porque esto es una brutalidad?

"Emerson" <emerson_sacar_arroba_leshalles.cl> escribió en el
mensaje news:%23F8xfC$%
quise hacer esta query, por ignorancia, porque al estudia EXISTS,
me di cuenta que lo que estoy haciendo es una brutalidad.

cómo lo debo hacer, si en la misma query quiero comprobar si
existen los valores, de no ser así ingresarlos.

gracias.

Emerson

IF NOT EXISTS (SELECT id_producto FROM PFP WHERE id_producto >>>>>> 10 AND id_forma_pago = 4)
(INSERT INTO PFP(id_producto, id_forma_pago) VALUES (10, 4))
Respuesta Responder a este mensaje
#13 Miguel Egea
03/03/2004 - 09:31 | Informe spam
Hola Javier, no se por que mi lector de noticias ha obviado tu mensaje, y
solo lo he visto dado que Emerson a conestado.
Estoy 99% de acuerdo contigo solo me queda una puntualización que tengo
clarísimo que tu conoces, pero que igual algún lector del hilo puede obviar
y es la siguiente
Si dentro de un sp ejecutas un if exists o cualqueir comando sin haber
empezado la transacción eso no garantiza en modo alguno que no estés dentro
de una transaccion, digo que no lo garantiza porque si el procedimiento es
invocado desde otro, o una aplicación en cualquier lenguaje usa las
transacciones de ADO o ADO.NET, seguramente ya estés en una transacción
dentro. En resumen, 100% de acuerdo contigo, pero ojo que hay que poner de
acuerdo en el tratamiento de transaciones en este caso a los desarrolladores
y a los DBAS. Yo personalmente prefiero que estos dos perfiles (que cumplo
ya que hago unas cosas y otras) no tengan que hablarse, ya sabes que para
los desarrolladores los DBAs somos muchas veces 'ese obstaculo a salvar',
preocupados por asuntos 'poco importantes', como el rendimiento, las
transacciones y esas cosillas, jeje. En cualquier caso y siendo sincero he
usado algunas veces ese modelo, aunque ahora después de algunos 'fenómenos
extraños' prefiero recuperarme del error.

La verdad es que este tipo de discusiones nos aportan mucho a todos, a ver
si nuestro amigo Carlos Sacristan además la resume y la 'Inmortalizamos' en
portalsql ::-)


¡Saludos!

"Emerson" <emerson_sacar_arroba_leshalles.cl> escribió en el mensaje
news:ePCaW1V$
es discusión de mayores, aquí sólo es mi deber aprender y agradecer.

EG

"Javier Loria" escribió en el mensaje
news:uS5eyEU$
> Hola Miguel:
> Yo creo que me estas provocando para que tengamos una discusion al
mejor
> estilo de la de identity ;). En todo caso siempre he sido muy tolerante


a
> este tipo de diferencias y es un placer intercambiar opiniones con un


gran
> conocedor de SQL, y aun cuando no tengas razon me obligas a cuestionar


mi
> "librito".
> En realidad si revisas mi sugerencia veras que los IF EXISTS(SELECT)
> estan ANTES de la TRANSACCION, por ende no estan generando BLOQUEOS!.
> De hecho este patron que genera menos bloqueos que el de tratar y
> probar, porque se deshace del 99% de los errores que ocurren ANTES DE
> INICIAR la Transaccion. Ejemplo: Si voy a realizar una serie de
modificacion
> (INSERT, DELETE, UPDATE) que puede fallar, (por PK, FK, CHECK, etc).
reviso
> antes de iniciar el proceso que se cumplan las reglas y si se cumplen
luego
> trato de ejecutarlos. Solo en el caso que algun otro usuario haya
cambiando
> las filas en ese momento se rompera la regla pero este sera unicamente


el
1%
> de las veces. Claro es posible que fallen por eso necesito siempre el:


IF
> @@Error. Pero solo fallan si se produce alguna modificacion


"simultanea".
> El patron pruebe si falla, tiene el problema que inicia la
transaccion,
> realiza modificaciones (bloqueando los registros involucrados),


disparando
> los triggers, y grabando en la bitacora del Log, para luego si hay un
error
> en la ultima actualizacion, hacer rollback de todo!!!. Esto es mas lento


y
> con mayor cantidad de bloqueos que el patron por mi posteado.
> Una ventaja adicional del patron posteado es que permite


personalizar
> los errores.
> Claro no todo es color de rosa en este esquema que sugeri, tiene
algunos
> problemas, principalmente:
> a) Obligar al desarrollador ha escribir mas codigo (haciendo mas


lento
> el proceso de generacion de software),
> b) Mayor costo de manenimiento (tengo que cambiar el CHECK y cambiar
el
> Procedimiento Almacenado).
> Esa es mi opinion, pero voy a ver si escribo alguna prueba de
desempeno.
> Saludos,
>
>
> Javier Loria
> Costa Rica
> Se aprecia la inclusion de DDL (CREATE, INSERTS, etc.)
> que pueda ser copiado y pegado al Query Analizer.
> La version de SQL y Service Pack tambien ayuda.
>
> Miguel Egea escribio:
> > A mi no me parece esa forma del todo correcta porque los patrones
> > SElect-insert tienen varios problemas
> > el primero es que si el nivel de aislamiento es bajo, nada garantiza
> > que dos puestos no ejecuten las sentencias justo en el orden en que
> > te de error por clave duplicada de todas formas. El segundo es que si
> > por el contrario pones un nivel de aislamiento alto, tienes muchas
> > posibilidades de obtener un deadlock en los mismos casos. Por eso me
> > decanto por recuperarme (en este caso) del error de pk.
> >
> >
> >
> > Miguel Egea
> > Microsoft SQL-SERVER MVP
> > Brigada Anti-Cursores
> > "Juan Carlos Leguizamón"
> > escribió en el mensaje news:eNXYXXK$
> >> Totalmente de acuerdo, ya decia yo que no podia estar tan equivocado
> >> en mis creencias ...
> >>
> >> "Javier Loria" escribió en el mensaje
> >> news:eefXfbJ$
> >>> Hola:
> >>> Pues a mi me parece que NO es una brutalidad y es perfectamente
> >>> valido el patron de INSERCION:
> >>> => > >>> IF NOT EXISTS (...)
> >>> BEGIN
> >>> INSERT .
> >>> END
> >>> => > >>> Yo particularmente soy mas amigo de:
> >>> => > >>> IF EXISTS(...)
> >>> BEGIN
> >>> RAISERROR(...)
> >>> ROLLBACK
> >>> END
> >>> IF EXISTS(..)
> >>> BEGING
> >>> RAISERROR(...)
> >>> ROLLBACK
> >>> END
> >>>
> >>> BEGIN TRAN
> >>> INSERT ...
> >>> IF @@ERROR <> THEN
> >>> INSERT ...
> >>> IF @@ERROR <> THEN
> >>> INSERT ...
> >>> COMMIT
> >>> => > >>> Pero me parece PERFECTAMENTE VALIDO el codigo que escribes.
> >>> Saludos,
> >>>
> >>>
> >>> Javier Loria
> >>> Costa Rica
> >>> Se aprecia la inclusion de DDL (CREATE, INSERTS, etc.)
> >>> que pueda ser copiado y pegado al Query Analizer.
> >>> La version de SQL y Service Pack tambien ayuda.
> >>> Emerson <emerson_sacar_arroba_leshalles.cl> escribio:
> >>>> ya que estaba ocupando EXISTS para validar los datos en una tabla y
> >>>> luego insertandoles, y me percate que EXISTS es para otra cosa, es
> >>>> más similar al IN...
> >>>>
> >>>> EG
> >>>>
> >>>>
> >>>> "Juan Carlos Leguizamón"
> >>>> escribió en el mensaje
> >>>> news:#wmNp4H$
> >>>>> Hola, esta vez no entendí. ¿porque esto es una brutalidad?
> >>>>>
> >>>>> "Emerson" <emerson_sacar_arroba_leshalles.cl> escribió en el
> >>>>> mensaje news:%23F8xfC$%
> >>>>>> quise hacer esta query, por ignorancia, porque al estudia EXISTS,
> >>>>>> me di cuenta que lo que estoy haciendo es una brutalidad.
> >>>>>>
> >>>>>> cómo lo debo hacer, si en la misma query quiero comprobar si
> >>>>>> existen los valores, de no ser así ingresarlos.
> >>>>>>
> >>>>>> gracias.
> >>>>>>
> >>>>>> Emerson
> >>>>>>
> >>>>>> IF NOT EXISTS (SELECT id_producto FROM PFP WHERE id_producto > > >>>>>> 10 AND id_forma_pago = 4)
> >>>>>> (INSERT INTO PFP(id_producto, id_forma_pago) VALUES (10, 4))
>
>


Respuesta Responder a este mensaje
#14 sinma10
05/03/2004 - 10:26 | Informe spam
Discusiones muy útiles para los que nos iniciamos y queremos aprender!
email Siga el debate Respuesta Responder a este mensaje
Ads by Google
Help Hacer una pregunta AnteriorRespuesta Tengo una respuesta
Search Busqueda sugerida