Ejecución de SP para múltiples registros

21/10/2005 - 23:00 por Enric | Informe spam
Hola,
Suponiendo una tabla asi
Tabla M(
Campo1 int
Campo2 int
Campo3 int)

y un SP así
alter procedure edita_Registro @var1 int, var2 int
as
...
...
update Tabla set Campo3 = .

Es posible ejecutar este SP para todos los registros de M pasándole como
parametros Campo1 y Campo2, para que el SP me actualize el Campo3?

Estaba pensando en hacerlo desde c# a trvés de un datareader leyendo
registro a registro y ejecutando el SP. Pero me gustaria saber si se puede
hacer mediante alguna consulta.

grácias,
Miquel

Preguntas similare

Leer las respuestas

#1 Maxi \(MVP SQL\)
21/10/2005 - 23:45 | Informe spam
Es posible pero no recomendado. Lo que es facil para el programador es un
enorme perjuciio para el motor. Para poder hacer esto vas a necesitar
SQL-Dinamico (sp_executesql) pero no te lo recomiendo
(http://www.hayes.ch/sql/sql_dinamico.html)


-
[MS-MVP SQL SERVER]

"Enric" escribió en el mensaje
news:%
Hola,
Suponiendo una tabla asi
Tabla M(
Campo1 int
Campo2 int
Campo3 int)

y un SP así
alter procedure edita_Registro @var1 int, var2 int
as
...
...
update Tabla set Campo3 = .

Es posible ejecutar este SP para todos los registros de M pasándole como
parametros Campo1 y Campo2, para que el SP me actualize el Campo3?

Estaba pensando en hacerlo desde c# a trvés de un datareader leyendo
registro a registro y ejecutando el SP. Pero me gustaria saber si se puede
hacer mediante alguna consulta.

grácias,
Miquel


Respuesta Responder a este mensaje
#2 Alejandro Mesa
22/10/2005 - 06:25 | Informe spam
Enric,

Que calculo realiza ese procedimeinto?


AMB

"Enric" wrote:

Hola,
Suponiendo una tabla asi
Tabla M(
Campo1 int
Campo2 int
Campo3 int)

y un SP así
alter procedure edita_Registro @var1 int, var2 int
as


update Tabla set Campo3 = .

Es posible ejecutar este SP para todos los registros de M pasándole como
parametros Campo1 y Campo2, para que el SP me actualize el Campo3?

Estaba pensando en hacerlo desde c# a trvés de un datareader leyendo
registro a registro y ejecutando el SP. Pero me gustaria saber si se puede
hacer mediante alguna consulta.

grácias,
Miquel



Respuesta Responder a este mensaje
#3 Enric
22/10/2005 - 23:17 | Informe spam
Hola,
El procedimiento es este:

ALTER procedure Metge_InsertaEspecialitatMetge
@CodiMetge int,
@Especialitats nvarchar(100)
as

delete from tblExM where lngCM = @CodiMetge
delete from tblSxM where lngCM = @CodiMetge

declare @CE int
declare @posInici int
declare @PosFi int
declare @especialitat nvarchar(5)
declare @num int
set @posInici = 1
set @posFi = 0
while (@posFi >= 0)
begin
select @posFi = CHARINDEX(' ',@Especialitats, @posInici)
if (@posFi = 0)
begin
set @especialitat = SUBSTRING(@Especialitats, @posInici,
LEN(@Especialitats))
set @posFi = -1
end
else
begin
set @especialitat = SUBSTRING(@Especialitats, @PosInici, @PosFi -
@PosInici)
set @posInici = @PosFi + 1
end
select @CE = lngCE from tblSxE where strCS = @Especialitat
if (not @CE is null)
begin
select @num = count(*) from tblExM where lngCM = @CodiMetge and lngCE @CE
if (@num = 0)
insert into tblExM (lngCM, lngCE) values (@CodiMetge, @CE)
end
select @num = count(*) from tblSxM where lngCM = @CodiMetge and strCS @Especialitat
if (@num = 0)
insert into tblSxM (lngCM, strCS) values (@CodiMetge, @Especialitat)
end

La definicion de las 3 tablas que intervienen son:
CREATE TABLE [tblExM] (
[lngCM] [int] NOT NULL ,
[lngCE] [int] NOT NULL ,
CONSTRAINT [PK_tblExM] PRIMARY KEY CLUSTERED
(
[lngCM],
[lngCE]
) ON [PRIMARY]
) ON [PRIMARY]
GO
CREATE TABLE [tblSxM] (
[lngCM] [int] NOT NULL ,
[strCS] [varchar] (5) COLLATE Modern_Spanish_CI_AI NOT NULL ,
CONSTRAINT [PK_tblSxM] PRIMARY KEY CLUSTERED
(
[lngCM],
[strCS]
) ON [PRIMARY]
) ON [PRIMARY]
GO
CREATE TABLE [tblSXE] (
[lngCE] [int] NOT NULL ,
[strCS] [varchar] (5) COLLATE Modern_Spanish_CI_AI NOT NULL ,
CONSTRAINT [PK_tblSXE] PRIMARY KEY CLUSTERED
(
[lngCE],
[strCS]
) ON [PRIMARY]
) ON [PRIMARY]
GO


Lo que hace el SP es que recibe como parametros un int (código de médico) y
una cadena del tipo "CA ES PRE GIN" y inserta registros con las palabras
separadas: O sea con "CA" "ES" "PRE" y "GIN", con su correspondiente código.
Esto, me funciona en el programa en producción puesto que lo ejecuto cuando
se inserta o modifica un médico (o sea, un sólo registro).
Pero me encuentro que de vez en cuando me llegan datos procedentes de
traspasos, y tengo que ejecutar esto para cada uno de los registros que me
llegan. Por esto la pregunta de si se puede ejecutar como una sola
instrucción, o es mejor que lo implemente desde código, recorriendo registro
a registro y ejecutando el SP para cada uno de ellos.

Muchas grácias por la atención.
Respuesta Responder a este mensaje
#4 Alejandro Mesa
23/10/2005 - 23:51 | Informe spam
Enric,

Vamos a ir por parte. Hay muchas cosas en este sp que podemos tratar de
mejorar.

Lo primero que vamos a hacer, es crear una funcion a la cual le pasaremos la
cadena nvarchar(100) y nos devolvera una tabla donde cada fila sera un
elemento de la cadena, de esta forma podremos insertar en las tablas tblExM
y tblSxM usando la sintaxis:

ALTER procedure dbo.Metge_InsertaEspecialitatMetge
@CodiMetge int,
@Especialitats varchar(100)
as
set nocount on

delete tblExM where lngCM = @CodiMetge
delete tblSxM where lngCM = @CodiMetge

insert into tblExM
select @CodiMetge, s.lngCE
from
dbo.ufn_inline_split_me(@Especialitats) as f
inner join
tblSxE as s where s.strCS = f.value
where
not exists(
select * from tblExM where lngCM = @CodiMetge and lngCE = s.lngCE
)

insert into tblSxM
select @CodiMetge, f.value
from
dbo.ufn_inline_split_me(@Especialitats) as f
where
not exists(
select * from tblSxM where lngCM = @CodiMetge and strCS = f.value
)

return
go

La funcion ya ha sido escrita y la puedes encontrar en el siguiente articulo
(te recomiendo que lo leas porque es fantastico):

Arrays and Lists in SQL Server
http://www.sommarskog.se/arrays-in-sql.html

La funcion se llama inline_split_me y deberas adaptarla a tu contexto porque
usa el caracter "," (la coma) como separador de lista y tu en cambio usas el
caracter de espacio.

En cuanto ha ejecutar este sp por cada fila que te lleha, no queda otra
opcion que crear un cursor o lazo para recorrer la tabla que te llega y
ejecutar el sp para cada una de ellas.

Ejemplo:

declare @rv int
declare @c1 int
declare @c2 varchar(5)
declare mi_cursor cursor
local
fast_forward
for
select c1, c2
from tabla_que_te_llega

open mi_cursor

while 1 = 1
begin
fetch next from mi_cursor into @c1, @c2

if @@error != 0 or @@fetch_status != 0 break

exec @rv = dbo.Metge_InsertaEspecialitatMetge(23, 'CA ES PRE GIN')

end

close mi_cursor
deallocate mi_cursor
go

Yo no tengo sql server en esta computer y por lo tanto no he probado el
codigo posteado.


AMB

"Enric" wrote:

Hola,
El procedimiento es este:

ALTER procedure Metge_InsertaEspecialitatMetge
@CodiMetge int,
@Especialitats nvarchar(100)
as

delete from tblExM where lngCM = @CodiMetge
delete from tblSxM where lngCM = @CodiMetge

declare @CE int
declare @posInici int
declare @PosFi int
declare @especialitat nvarchar(5)
declare @num int
set @posInici = 1
set @posFi = 0
while (@posFi >= 0)
begin
select @posFi = CHARINDEX(' ',@Especialitats, @posInici)
if (@posFi = 0)
begin
set @especialitat = SUBSTRING(@Especialitats, @posInici,
LEN(@Especialitats))
set @posFi = -1
end
else
begin
set @especialitat = SUBSTRING(@Especialitats, @PosInici, @PosFi -
@PosInici)
set @posInici = @PosFi + 1
end
select @CE = lngCE from tblSxE where strCS = @Especialitat
if (not @CE is null)
begin
select @num = count(*) from tblExM where lngCM = @CodiMetge and lngCE > @CE
if (@num = 0)
insert into tblExM (lngCM, lngCE) values (@CodiMetge, @CE)
end
select @num = count(*) from tblSxM where lngCM = @CodiMetge and strCS > @Especialitat
if (@num = 0)
insert into tblSxM (lngCM, strCS) values (@CodiMetge, @Especialitat)
end

La definicion de las 3 tablas que intervienen son:
CREATE TABLE [tblExM] (
[lngCM] [int] NOT NULL ,
[lngCE] [int] NOT NULL ,
CONSTRAINT [PK_tblExM] PRIMARY KEY CLUSTERED
(
[lngCM],
[lngCE]
) ON [PRIMARY]
) ON [PRIMARY]
GO
CREATE TABLE [tblSxM] (
[lngCM] [int] NOT NULL ,
[strCS] [varchar] (5) COLLATE Modern_Spanish_CI_AI NOT NULL ,
CONSTRAINT [PK_tblSxM] PRIMARY KEY CLUSTERED
(
[lngCM],
[strCS]
) ON [PRIMARY]
) ON [PRIMARY]
GO
CREATE TABLE [tblSXE] (
[lngCE] [int] NOT NULL ,
[strCS] [varchar] (5) COLLATE Modern_Spanish_CI_AI NOT NULL ,
CONSTRAINT [PK_tblSXE] PRIMARY KEY CLUSTERED
(
[lngCE],
[strCS]
) ON [PRIMARY]
) ON [PRIMARY]
GO


Lo que hace el SP es que recibe como parametros un int (código de médico) y
una cadena del tipo "CA ES PRE GIN" y inserta registros con las palabras
separadas: O sea con "CA" "ES" "PRE" y "GIN", con su correspondiente código.
Esto, me funciona en el programa en producción puesto que lo ejecuto cuando
se inserta o modifica un médico (o sea, un sólo registro).
Pero me encuentro que de vez en cuando me llegan datos procedentes de
traspasos, y tengo que ejecutar esto para cada uno de los registros que me
llegan. Por esto la pregunta de si se puede ejecutar como una sola
instrucción, o es mejor que lo implemente desde código, recorriendo registro
a registro y ejecutando el SP para cada uno de ellos.

Muchas grácias por la atención.






Respuesta Responder a este mensaje
#5 Alejandro Mesa
24/10/2005 - 00:21 | Informe spam
Correccion:

exec @rv = dbo.Metge_InsertaEspecialitatMetge(23, 'CA ES PRE GIN')



exec @rv = dbo.Metge_InsertaEspecialitatMetge(@c1, @c2)


AMB


"Alejandro Mesa" wrote:

Enric,

Vamos a ir por parte. Hay muchas cosas en este sp que podemos tratar de
mejorar.

Lo primero que vamos a hacer, es crear una funcion a la cual le pasaremos la
cadena nvarchar(100) y nos devolvera una tabla donde cada fila sera un
elemento de la cadena, de esta forma podremos insertar en las tablas tblExM
y tblSxM usando la sintaxis:

ALTER procedure dbo.Metge_InsertaEspecialitatMetge
@CodiMetge int,
@Especialitats varchar(100)
as
set nocount on

delete tblExM where lngCM = @CodiMetge
delete tblSxM where lngCM = @CodiMetge

insert into tblExM
select @CodiMetge, s.lngCE
from
dbo.ufn_inline_split_me(@Especialitats) as f
inner join
tblSxE as s where s.strCS = f.value
where
not exists(
select * from tblExM where lngCM = @CodiMetge and lngCE = s.lngCE
)

insert into tblSxM
select @CodiMetge, f.value
from
dbo.ufn_inline_split_me(@Especialitats) as f
where
not exists(
select * from tblSxM where lngCM = @CodiMetge and strCS = f.value
)

return
go

La funcion ya ha sido escrita y la puedes encontrar en el siguiente articulo
(te recomiendo que lo leas porque es fantastico):

Arrays and Lists in SQL Server
http://www.sommarskog.se/arrays-in-sql.html

La funcion se llama inline_split_me y deberas adaptarla a tu contexto porque
usa el caracter "," (la coma) como separador de lista y tu en cambio usas el
caracter de espacio.

En cuanto ha ejecutar este sp por cada fila que te lleha, no queda otra
opcion que crear un cursor o lazo para recorrer la tabla que te llega y
ejecutar el sp para cada una de ellas.

Ejemplo:

declare @rv int
declare @c1 int
declare @c2 varchar(5)
declare mi_cursor cursor
local
fast_forward
for
select c1, c2
from tabla_que_te_llega

open mi_cursor

while 1 = 1
begin
fetch next from mi_cursor into @c1, @c2

if @@error != 0 or @@fetch_status != 0 break

exec @rv = dbo.Metge_InsertaEspecialitatMetge(23, 'CA ES PRE GIN')

end

close mi_cursor
deallocate mi_cursor
go

Yo no tengo sql server en esta computer y por lo tanto no he probado el
codigo posteado.


AMB

"Enric" wrote:

> Hola,
> El procedimiento es este:
>
> ALTER procedure Metge_InsertaEspecialitatMetge
> @CodiMetge int,
> @Especialitats nvarchar(100)
> as
>
> delete from tblExM where lngCM = @CodiMetge
> delete from tblSxM where lngCM = @CodiMetge
>
> declare @CE int
> declare @posInici int
> declare @PosFi int
> declare @especialitat nvarchar(5)
> declare @num int
> set @posInici = 1
> set @posFi = 0
> while (@posFi >= 0)
> begin
> select @posFi = CHARINDEX(' ',@Especialitats, @posInici)
> if (@posFi = 0)
> begin
> set @especialitat = SUBSTRING(@Especialitats, @posInici,
> LEN(@Especialitats))
> set @posFi = -1
> end
> else
> begin
> set @especialitat = SUBSTRING(@Especialitats, @PosInici, @PosFi -
> @PosInici)
> set @posInici = @PosFi + 1
> end
> select @CE = lngCE from tblSxE where strCS = @Especialitat
> if (not @CE is null)
> begin
> select @num = count(*) from tblExM where lngCM = @CodiMetge and lngCE > > @CE
> if (@num = 0)
> insert into tblExM (lngCM, lngCE) values (@CodiMetge, @CE)
> end
> select @num = count(*) from tblSxM where lngCM = @CodiMetge and strCS > > @Especialitat
> if (@num = 0)
> insert into tblSxM (lngCM, strCS) values (@CodiMetge, @Especialitat)
> end
>
> La definicion de las 3 tablas que intervienen son:
> CREATE TABLE [tblExM] (
> [lngCM] [int] NOT NULL ,
> [lngCE] [int] NOT NULL ,
> CONSTRAINT [PK_tblExM] PRIMARY KEY CLUSTERED
> (
> [lngCM],
> [lngCE]
> ) ON [PRIMARY]
> ) ON [PRIMARY]
> GO
> CREATE TABLE [tblSxM] (
> [lngCM] [int] NOT NULL ,
> [strCS] [varchar] (5) COLLATE Modern_Spanish_CI_AI NOT NULL ,
> CONSTRAINT [PK_tblSxM] PRIMARY KEY CLUSTERED
> (
> [lngCM],
> [strCS]
> ) ON [PRIMARY]
> ) ON [PRIMARY]
> GO
> CREATE TABLE [tblSXE] (
> [lngCE] [int] NOT NULL ,
> [strCS] [varchar] (5) COLLATE Modern_Spanish_CI_AI NOT NULL ,
> CONSTRAINT [PK_tblSXE] PRIMARY KEY CLUSTERED
> (
> [lngCE],
> [strCS]
> ) ON [PRIMARY]
> ) ON [PRIMARY]
> GO
>
>
> Lo que hace el SP es que recibe como parametros un int (código de médico) y
> una cadena del tipo "CA ES PRE GIN" y inserta registros con las palabras
> separadas: O sea con "CA" "ES" "PRE" y "GIN", con su correspondiente código.
> Esto, me funciona en el programa en producción puesto que lo ejecuto cuando
> se inserta o modifica un médico (o sea, un sólo registro).
> Pero me encuentro que de vez en cuando me llegan datos procedentes de
> traspasos, y tengo que ejecutar esto para cada uno de los registros que me
> llegan. Por esto la pregunta de si se puede ejecutar como una sola
> instrucción, o es mejor que lo implemente desde código, recorriendo registro
> a registro y ejecutando el SP para cada uno de ellos.
>
> Muchas grácias por la atención.
>
>
>
>
>
>
Respuesta Responder a este mensaje
Ads by Google
Help Hacer una preguntaSiguiente Respuesta Tengo una respuesta
Search Busqueda sugerida