Domanda

Ho una procedura memorizzata MSSQL2005 qui, che dovrebbe prendere un messaggio XML come input e archiviarne il contenuto in una tabella. I campi della tabella sono varchars, perché la nostra applicazione backend delphi non è in grado di gestire unicode. Ora, i messaggi che arrivano, sono codificati ISO-8859-1. Tutto va bene fino a quando i caratteri sopra > Sono inclusi 128 set standard (in questo caso, ÄÖäö, che sono parte integrante del finlandese). In questo modo il server DB genera l'eccezione 0xc00ce508. Le regole di confronto predefinite del database, nonché quelle di tabella e campo, sono impostate su latin1, che dovrebbe essere uguale a ISO-8859-1.

Il messaggio XML viene analizzato utilizzando il sottosistema XML, in questo modo:

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

In precedenza, la procedura memorizzata utilizzava nvarchar per l'input, ma poiché ciò causava problemi con l'antica applicazione di backend (Delphi 5 + ODBC), dovevamo cambiare i campi in varchars, a quel punto tutto si è rotto.

Ho anche provato a prendere nvarchar e convertirlo in varchar all'inizio, ma il risultato è lo stesso.

È stato utile?

Soluzione

Non so se qualcuno con abbastanza diritti per modificare la risposta vedrà questo, ma mentre la risposta è corretta, vorrei aggiungere che senza specificare esplicitamente le regole di confronto, in questo caso verrebbero utilizzate le regole di confronto predefinite del database è implicitamente assegnato a ogni variabile varchar senza una dichiarazione di confronto.

DECLARE @XmlDocument VARCHAR(2000) COLLATE SQL_Latin1_General_CP1_CI_AS

dovrebbe fare anche il trucco.

Altri suggerimenti

Risponderò alla mia domanda, poiché sono riuscito a risolvere il problema più che criptico ...

1) La procedura memorizzata deve riflettere la tabella codici corretta per la trasformazione:

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

2) L'input XML deve specificare lo stesso set di caratteri:

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

Il codice di errore che menzioni sembra provenire dalla libreria MSXML. Come è coinvolto lì? Dalla tua domanda suppongo che passi un parametro varchar a una procedura memorizzata, quindi inserisci o aggiorni una colonna varchar con quel parametro.

Tuttavia, ciò non corrisponde al tuo codice di eccezione, quindi deve avvenire al di fuori della procedura memorizzata effettiva o stai facendo cose aggiuntive basate su xml all'interno della procedura memorizzata.

Controlla e modifica la tua domanda di conseguenza.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top