SQL Server 2005/Хранимая процедура XML – Unicode в ascii?(Исключение 0xc00ce508)

StackOverflow https://stackoverflow.com/questions/119477

Вопрос

У меня есть хранимая процедура MSSQL2005, которая должна принимать XML-сообщение в качестве входных данных и сохранять его содержимое в таблице.Поля таблицы представляют собой символы varchars, поскольку наше серверное приложение Delphi не может обрабатывать Юникод.Теперь поступающие сообщения имеют кодировку ISO-8859-1.Все в порядке, пока не будут включены символы, превышающие стандартный набор > 128 (в данном случае ÄÖäö, которые являются неотъемлемой частью финского языка).Это приводит к тому, что сервер БД вызывает исключение 0xc00ce508.По умолчанию для базы данных, а также для таблицы и поля установлено значение latin1, которое должно совпадать с ISO-8859-1.

XML-сообщение анализируется с использованием подсистемы XML, например:

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

Раньше хранимая процедура использовала для ввода nvarchar, но поскольку это вызывало проблемы с древним серверным приложением (Delphi 5 + ODBC), нам пришлось переключить поля на varchars, и на этом этапе все сломалось.

Я также попробовал взять nvarchar и с самого начала преобразовать его в varchar, но результат тот же.

Это было полезно?

Решение

Я не знаю, увидит ли это кто-нибудь с достаточными правами для редактирования ответа, но, хотя ответ правильный, я хотел бы добавить, что без явного указания параметров сортировки в этом случае будет использоваться параметр сортировки базы данных по умолчанию, поскольку он неявно присваивается каждой переменной varchar без оператора сопоставления.

Так

DECLARE @XmlDocument VARCHAR(2000) COLLATE SQL_Latin1_General_CP1_CI_AS

тоже должно сработать.

Другие советы

Я отвечу на свой вопрос, поскольку мне удалось решить более чем загадочную проблему...

1) Хранимая процедура должна отражать правильную кодовую страницу для преобразования:

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

2) Во входных данных XML должна быть указана одна и та же кодировка:

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

Упоминаемый вами код ошибки, похоже, взят из библиотеки MSXML.Как это там связано?Судя по вашему вопросу, я бы предположил, что вы передаете параметр varchar в хранимую процедуру, а затем вставляете или обновляете столбец varchar с этим параметром.

Однако это не соответствует вашему коду исключения, поэтому это должно произойти за пределами фактической хранимой процедуры, или вы делаете дополнительные действия на основе XML внутри хранимой процедуры.

Пожалуйста, проверьте это и соответствующим образом измените свой вопрос.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top