Pregunta

Tengo un procedimiento almacenado MSSQL2005 aquí, que se supone que toma un mensaje XML como entrada y almacena su contenido en una tabla.Los campos de la tabla son varchars, porque nuestra aplicación backend de Delphi no pudo manejar Unicode.Ahora, los mensajes que llegan están codificados ISO-8859-1.Todo está bien hasta que se incluyan caracteres superiores al conjunto estándar > 128 (en este caso, ÄÖäö, que son parte integral del finlandés).Esto hace que el servidor de base de datos genere la excepción 0xc00ce508.La intercalación predeterminada de la base de datos, así como la de las tablas y los campos, está configurada en latin1, que debería ser la misma que ISO-8859-1.

El mensaje XML se analiza utilizando el subsistema XML, así:

ALTER PROCEDURE [dbo].[parse] @XmlIn NVARCHAR(1000) AS
SET NOCOUNT ON
DECLARE @XmlDocumentHandle INT
DECLARE @XmlDocument VARCHAR(1000)
BEGIN
SET @XmlDocument = @XmlIn
EXECUTE sp_xml_preparedocument @XmlDocumentHandle OUTPUT, @XmlDocument
BEGIN TRANSACTION
//the xml message's fields are looped through here, and rows added or modified in two tables accordingly
// like ...
DECLARE TempCursor CURSOR FOR
SELECT AM_WORK_ID,CUSTNO,STYPE,REFE,VIN_NUMBER,REG_NO,VEHICLE_CONNO,READY_FOR_INVOICE,IS_SP,SMANID,INVOICENO,SUB_STATUS,TOTAL,TOTAL0,VAT,WRKORDNO
FROM OPENXML (@XmlDocumentHandle, '/ORDER_NEW_CP_REQ/ORDER_NEW_CUSTOMER_REQ',8)
WITH (AM_WORK_ID int '@EXIDNO',CUSTNO int '@CUSTNO',STYPE VARCHAR(1) '@STYPE',REFE VARCHAR(50) '@REFE',VIN_NUMBER VARCHAR(30) '@VEHICLE_VINNO',
REG_NO VARCHAR(20) '@VEHICLE_LICNO',VEHICLE_CONNO VARCHAR(30) '@VEHICLE_CONNO',READY_FOR_INVOICE INT '@READY_FOR_INVOICE',IS_SP INT '@IS_SP',
SMANID INT '@SMANID',INVOICENO INT '@INVOICENO',SUB_STATUS VARCHAR(1) '@SUB_STATUS',TOTAL NUMERIC(12,2) '@TOTAL',TOTAL0 NUMERIC(12,2) '@TOTAL0',VAT NUMERIC(12,2) '@VAT',WRKORDNO INT '@WRKORDNO')
OPEN TempCursor
FETCH NEXT FROM TempCursor
INTO @wAmWork,@wCustNo,@wType,@wRefe,@wVIN,@wReg,@wConNo,@wRdy,@wIsSp,@wSMan,@wInvoNo,@wSubStatus,@wTot,@wTot0,@wVat,@wWrkOrdNo
// ... etc
COMMIT TRANSACTION
EXECUTE sp_xml_removedocument @XmlDocumentHandle
END

Anteriormente, el procedimiento almacenado solía usar nvarchar como entrada, pero como eso causaba problemas con la antigua aplicación backend (Delphi 5 + ODBC), tuvimos que cambiar los campos a varchars, momento en el que todo se rompió.

También intenté tomar nvarchar y convertirlo a varchar al principio, pero el resultado es el mismo.

¿Fue útil?

Solución

No sé si alguien con suficientes derechos para editar la respuesta verá esto, pero si bien la respuesta es correcta, me gustaría agregar que sin especificar la intercalación explícitamente, en este caso se usaría la intercalación predeterminada de la base de datos, ya que está implícitamente asignado a cada variable varchar sin una declaración de intercalación.

Entonces

DECLARE @XmlDocument VARCHAR(2000) COLLATE SQL_Latin1_General_CP1_CI_AS

También debería funcionar.

Otros consejos

Responderé mi propia pregunta, ya que logré resolver el problema más que críptico...

1) El procedimiento almacenado debe reflejar la página de códigos correcta para la transformación:

@XmlIn NVARCHAR(2000)
@XmlDocument VARCHAR(2000)
SELECT @XmlDocument = @XmlIn COLLATE SQL_Latin1_General_CP1_CI_AS

2) La entrada XML debe especificar el mismo juego de caracteres:

<?xml version="1.0" encoding="ISO-8859-1" ?>

El código de error que mencionas parece provenir de la biblioteca MSXML.¿Cómo se relaciona eso ahí?Según su pregunta, asumiría que pasa un parámetro varchar a un procedimiento almacenado y luego inserta o actualiza una columna varchar con ese parámetro.

Sin embargo, eso no coincide con su código de excepción, por lo que debe suceder fuera del procedimiento almacenado real o estará haciendo cosas adicionales basadas en xml dentro del procedimiento almacenado.

Verifique eso y modifique su pregunta en consecuencia.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top