PrefSuite - Compresión de campos XML

Anuncio
Compresión de campos XML
Nota técnica 2008.1.017
Junio de 2009
Ronda Guglielmo Marconi, 9
Parque Tecnológico
46980 Paterna | Valencia | Spain
T |+34| 96 338 99 66
[email protected]
www.prefsuite.com
Please
Recycle
PrefSuite
Document
PrefSuite
www.prefsuite.com
En PrefSuite 2008.1 y 2008.2, se ha modificado la forma de guardar los XMLs descriptivos tanto en el
apartado de documentos de ventas como en producción. Así mismo, también se han modificado la
forma de guardar los XMLs de serialización en los documentos de ventas.
Los XMLs descriptivos y de serialización de los documentos de ventas se guardan en la tabla
ContenidoPAFBLOB. El usuario puede elegir la forma de guardar estos XMLs mediante una variable
global que se debe introducir en la tabla VariablesGlobales. El nombre de esta variable es
PrefItems.ZipXmls. Cuando esta variable existe y tiene valor igual a ‘1’, los XMLs se guardarán
comprimidos en la tabla ContenidoPAFBLOB. El XML descriptivo de cada línea se almacena en el
campo XMLDescriptive y el de serialización en el campo Buffer. Si la variable no existe o tiene un valor
distinto, los XMLs se guardarán sin comprimir en los campos XML y XMLSerialization
respectivamente.
Para ver si existe esta variable, habrá que ejecutar el siguiente script en el Management Studio de SQL:
SELECT * FROM VariablesGlobales WHERE Nombre='PrefItems.ZipXmls'
Este indicará si existe el registro en la tabla o no. Por tanto:
a) Si existe, y en el campo “Valor” aplica “0”, habrá que modificar dicho campo a “1”. Para cambiar el
valor de esta variable a “1”, la instrucción a ejecutar será:
UPDATE VariablesGlobales SET Valor=1 WHERE Nombre='PrefItems.ZipXmls'
b) En caso de que no exista la variable en la tabla “VariablesGlobales”, habrá que insertarla y aplicarle
el valor deseado. Esta acción se aplica ejecutando la siguiente sentencia SQL:
INSERT INTO VariablesGlobales (Empresa, Nombre, Valor)
VALUES (1,'PrefItems.ZipXmls', 1)
PrefSuite es compatible con líneas guardadas en ambos formatos. Todos los accesos de
lectura/escritura del kernel a estos XMLs han sido revisados para soportar ambos formatos. Por tanto,
no es necesario realizar ningún proceso de conversión de datos para utilizar una forma de guardado u
otra, y se puede cambiar tantas veces como se desee sin incurrir por ello en ningún coste.
Los accesos que se realizan desde fuera del kernel (DLLs de usuario) deben ser modificados para ser
compatibles con ambos formatos. La forma correcta de acceder al XML de una línea de un documento
de ventas es usando la función SQL llamada dbo.Sales_GetItemDescriptiveXml. Para el XML de
serialización es necesario usar la función dbo.Sales_GetItemSerializationXml. Ambas aceptan como
parámetros el número, versión y orden de la línea de la cual se desea obtener el XML. Estas funciones
leen el XML del campo adecuado y lo descomprimen si es necesario. Hay que señalar que en el caso de
que deban descomprimir el XML, lo hacen en el propio servidor SQL, por lo que tienen que ser
llamadas con cuidado a fin de evitar una excesiva carga de la CPU en el servidor.
Los XMLs descriptivos de producción, se guardan siempre comprimidos. La variable global no les
afecta. Se guardan en la tabla PrefItems.ItemDescriptiveXmls, en el campo XmlBlob. EL DBManager se
encarga de realizar la compresión de los datos antiguos.
Compresión de campos XML | Technical Note 2008.1.017 | 2
PrefSuite
www.prefsuite.com
Los accesos al XML de producción deben realizarse utilizando la función SQL
dbo.Production_GetItemDescriptiveXml, que acepta como parámetros el número de lote, y el número,
versión y orden del documento de ventas.
Una vez activada la compresión en una base de datos, se puede usar el script que se indica a
continuación para comprimir poco a poco la tabla ContenidoPAFBlob.
Antes de ejecutar el script hay que configurarle las variables @startDate y @endDate con el rango de
fechas de los documentos a comprimir.
El proceso puede ser muy lento, así que se recomienda no usar grandes rangos de documentos porque
se podría bloquear el servidor SQL. Se puede ir haciendo poco a poco. Se recomienda hacerlo fuera del
horario de oficina.
Imprescindible disponer de un backup completo de la base de datos antes de ejecutar el script.
El hecho de comprimir los datos no va a reducir el tamaño de una base de datos en disco, pero sí que
va a dejar espacio libre dentro del espacio reservado para la base de datos. Sólo tras compactar la base
de datos se liberaría el espacio no utilizado. Pero es bueno que las bases de datos tengan espacio de más
reservado; así que no se recomienda compactar salvo que sea necesario o que el espacio reservado sea
muy superior al utilizado.
El script es el siguiente:
ALTER TABLE ContenidoPAFBlob DISABLE TRIGGER ALL
GO
SET NOCOUNT ON;
-- Configure range of documents to convert
DECLARE @start_date AS datetime = '2009-01-01 00:00:00'
DECLARE @end_date AS datetime = '2009-03-31 00:00:00'
-DECLARE
DECLARE
DECLARE
DECLARE
DECLARE
DECLARE
DECLARE
DECLARE
@number AS int
@version AS int
@order AS int
@date AS datetime
@counter AS int = 1
@total AS int
@space_before AS nvarchar(max)
@space_after AS nvarchar(max)
DECLARE @space_used table(name nvarchar(max), rows int, reserved nvarchar(max), data
nvarchar(max), index_sisze nvarchar(max), unused nvarchar(max))
INSERT INTO @space_used exec sp_spaceused ContenidoPAFBlob
SELECT @space_before=data FROM @space_used
DELETE FROM @space_used
SELECT @total=COUNT(*)
FROM ContenidoPAF CP
INNER JOIN PAF P ON P.Numero = CP.Numero AND P.Version = CP.Version
WHERE P.FechaSolicitud >= @start_date AND P.FechaSolicitud < @end_date
PRINT CONVERT(nvarchar(max),GETDATE(),108) + N' - Start processing ' +
CONVERT(nvarchar(max),@total) + N' items.'
DECLARE ContenidoPAFCursor CURSOR FAST_FORWARD FOR
Compresión de campos XML | Technical Note 2008.1.017 | 3
PrefSuite
www.prefsuite.com
SELECT CP.Numero, CP.Version, CP.Orden, P.FechaSolicitud
FROM ContenidoPAF CP
INNER JOIN PAF P ON P.Numero = CP.Numero AND P.Version = CP.Version
WHERE P.FechaSolicitud >= @start_date AND P.FechaSolicitud < @end_date
ORDER BY P.FechaSolicitud ASC
OPEN ContenidoPAFCursor
FETCH NEXT FROM ContenidoPAFCursor INTO @number, @version, @order, @date
WHILE ( @@FETCH_STATUS = 0 AND @@ERROR = 0 )
BEGIN
SET @counter = @counter+1
UPDATE CPB
SET CPB.XmlDescriptive = zlib.ZipXml (CPB.xml), CPB.xml = NULL
FROM ContenidoPAFBLOB CPB
WHERE CPB.Xml IS NOT NULL AND CPB.Numero=@number AND CPB.Version=@version AND
CPB.Orden=@order
UPDATE CPB
SET CPB.Buffer = zlib.ZipXml (CPB.XMLSerialization), CPB.XMLSerialization = NULL
FROM ContenidoPAFBLOB CPB
WHERE CPB.XMLSerialization IS NOT NULL AND CPB.Numero=@number AND
CPB.Version=@version AND CPB.Orden=@order
UPDATE CPB
SET CPB.XMLPricesBlob = zlib.ZipXml (CPB.XmlPrices), CPB.XmlPrices = NULL
FROM ContenidoPAFBLOB CPB
WHERE CPB.XmlPrices IS NOT NULL AND CPB.Numero=@number AND CPB.Version=@version AND
CPB.Orden=@order
IF @counter % 100 = 0
BEGIN
PRINT CONVERT(nvarchar(max),GETDATE(),108) + N' - Processed ' +
CONVERT(nvarchar(max),@counter) + N' items until ' + CONVERT(nvarchar(max),@date, 103)
END
FETCH NEXT FROM ContenidoPAFCursor INTO @number, @version, @order, @date
END
CLOSE ContenidoPAFCursor
DEALLOCATE ContenidoPAFCursor
INSERT INTO @space_used exec sp_spaceused ContenidoPAFBlob
SELECT @space_after=data FROM @space_used
PRINT CONVERT(nvarchar(max),GETDATE(),108) + N' - Terminated processing ' +
CONVERT(nvarchar(max),@counter) + N' items.'
PRINT CONVERT(nvarchar(max),GETDATE(),108) + N' - Data in table was ' + @space_before +
N' and now is ' + @space_after + N'.'
GO
ALTER TABLE ContenidoPAFBlob ENABLE TRIGGER ALL
GO
Compresión de campos XML | Technical Note 2008.1.017 | 4
Documentos relacionados
Descargar