Rubén Garrigós
Solid Quality Mentors
declare @ComandoBCP varchar(100)
set @ComandoBCP = 'bcp "SELECT * FROM Northwind..Categories" queryout
"c:\PruebaMonitor\authors.txt" -T -c'
exec master..xp_cmdshell @comandoBCP, no_output"
A XLS:
"create trigger Prueba on Categories
after update
as
INSERT INTO OPENROWSET ('Microsoft.Jet.OLEDB.4.0', 'Excel
8.0;Database=c:\contact.xls;',
'SELECT * FROM [Hoja1$]')
SELECT TOP 5 customerid,companyname
FROM Customers
GO"
a XML
"create trigger TriggerXML on Customers
for insert
as
declare @outputfile nvarchar(100),
@query nvarchar(100),
@templatefile nvarchar(100)
exec sp_makewebtask @outputfile = 'c:\myxmlfile.xml',
@query = 'select top 5 * from Customer"
La consulta la hice sobre tablas diferentes a las que disparan los
eventos del trigger, para evitar bloqueos, pero sigue sin andar. Vos
sabes bien si es posible ejecutar este tipo de consultas directamente
desde un trigger? Porque eso es crítico para la aplicación que tengo
que desarrollar.
Muchas gracias por tomarte el tiempo de responder.
En principio al primer trigger con bcp que comentas no le encuentro ningún
problema como para que no funcione. ¿Has probado de ejecutar las sentencias
del trigger a mano? Debería volcarte la tabla sin problema. Si no lo hace,
puede que sea un tema de permisos en esa carpeta pues en principio lo veo
todo bien. Prueba también a quitar el "no output" para ver si te devuelve
algún error más inteligible el bcp.
En todo caso, ten en cuenta que lanzar una consulta no dispara ningún
trigger. Únicamente cuando realices alguna modificación sobre la tabla
customers obtendrás el volcado de las categorías de northwind.
En el caso que te comentaba que el volcado afectara a alguna de las tablas
sobre las que actúa el trigger el problema de bloqueo que puedas tener lo
puedes aliviar (aunque no me guste mucho) añadiendo lectura sucia a tu
consulta (nolock).
Rubén Garrigós
Solid Quality Mentors
"create trigger MonitorCustomers
on Customers after update, insert, delete
as
select * into tempinserted from inserted
declare @ComandoBCP varchar(100)
set @ComandoBCP = 'bcp "SELECT * FROM Northwind..tempinserted"
queryout "c:\authors.txt" -T -c'
exec master..xp_cmdshell @comandoBCP"
Si yo ejecuto, por ejemplo:
"insert into Customers (customerid, companyname)
values('pepee','aaaaaaaa')"
Al usar tempinserted en la consulta BCP ejecuta eternamente, si por
ejemplo pongo products, que no la usa el trigger, si me exporta bien
los datos y el trigger finaliza sin errores, será porque el trigger
tiene un bloqueo sobre tempinserted? Como hago para esquivarlo? Leí
sobre el read uncomitted pero no se bien donde aplicarlo.
Muchisimas gracias de nuevo.
La implementación que comentas tiene el inconveniente de estar utilizando
una tabla que creas con un SELECT INTO lo cual te dará problemas en la
segunda ejecución al existir ya la tabla. Además, no es posible que lo hagas
de esta forma si luego vas a tener un BCP al tener ya una operación bulk como
SELECT INTO.
La solución a esto pasa por crearte una tabla de cambios para cada tabla que
quieras monitorizar previamente (a mano o con un select * into
customers_cambio from customers where 1=2). Esta tabla tendrá las mismas
columnas que la tabla original (en este caso customers). En el cuerpo del
trigger tendrías que sustituir el SELECT INTO por:
DELETE customers_cambios
INSERT customers_cambios
SELECT * FROM inserted
INSISTO, NO me gusta nada esta solución pues además de graves problemas de
rendimiento tiene problemas de concurrencia, de machaque del fichero ante
varios cambios, etc.
Creo que deberías replantearte seriamente lo de insertar en ficheros en el
mismo trigger. Podrías tener una solución mucho más elegante creandote tablas
para auditoria y utilizar el trigger para irlas rellenando con datos.
Periodicamente podrías volcarlas a disco si lo deseas también pero no
directamente en el trigger como pretendes hacer...
Rubén Garrigós
Solid Quality Mentors
"tulka...@hotmail.com" wrote:
"create trigger MonitorCustomers
on Customers after update, insert, delete
as
delete tabla_cambios
insert tabla_cambios
select customerid,companyname from inserted
declare @ComandoBCP varchar(100)
set @ComandoBCP = 'bcp "SELECT * FROM Northwind..tabla_cambios"
queryout "c:\authors.txt" -T -c'
exec master..xp_cmdshell @comandoBCP"
Cualquier operacion causa que el trigger quede congelado procesando,
se ve que al referenciar tabla_cambios, esta queda bloqueada. Se te
ocurre otra alternativa para ejecutar el bulk copy desde el trigger?
Alguna forma de mantener sin locks tabla_cambios?
Muchas gracias por la ayuda.
Añade el hint (nolock) a la consulta del bcp para permitir que lea datos
sucios, con eso debería funcionarte:
SELECT * FROM Northwind.dbo.tabla_cambios (nolock)
Entiendo que en ocasiones uno se encuentre entre la espada y la pared, pero
es importante, al menos, que los responsables sean consciente que hacer esto
es poco recomendable, propenso a problemas, etc.
Rubén Garrigós
Solid Quality Mentors
> queryout "c:\authors.txt" -T -c'