Тип данных SQL Server varchar(MAX) в Delphi с использованием RemObjects

Получил запрос на изменение максимального размера поля комментария в приложении. До этого он был установлен на varchar(500), поэтому после прочтения документации я решил изменить тип данных поля с varchar(500) на varchar(max). База данных приняла изменения без каких-либо проблем (с использованием Microsoft SQL Server Management Studio 2005 и Microsoft SQL Server Management Studio 2008 для управления базой данных). Затем я продолжал менять программное обеспечение. Программное обеспечение написано на Delphi с RemObjects для связи с базой данных. Поэтому я изменил TDASchema для сервера, он сопоставил мое новое поле varchar(max) с типом данных String(65536) (меня это немного беспокоило из-за такого явного статического размера, но я продолжил). Затем я получил схему DataTable для моего объекта TDAMemDataTable, который обновил все поля.

Я запустил приложение и решил посмотреть, будет ли моя база данных принимать изменения в этом конкретном измененном поле. Я отредактировал одну из записей и нажал кнопку, чтобы синхронизировать DataSet с сервером, и получил такое сообщение об ошибке:

Типы данных varchar(max) и text несовместимы в операторе равенства

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

Как это можно решить? Какие есть альтернативы?

PS В этом выпуске журналы Build .1267 от RemObjects четко говорится, что:

исправлено: DataSnap: не удается опубликовать обновления для MSSQL 2005 VARCHAR(MAX)

Я использую версию сборки.1067. Интересно, если обновление решит проблему

PPS После обновления до последней версии RemObjects проблема сохраняется.

3 ответа

Как вы и подозревали, я думаю, что корень ваших проблем в том, что поля не вошли в TDASchema как правильные типы. Я только что попробовал здесь, и поля varchar(max) и nvarchar(max) попадают в мою схему как Memo и WideMemo соответственно, а не String(65536).

Я использую Delphi XE6 и SQL Server 2008 R2 через FireDAC.

Это говорит о проблеме извлечения метаданных из базы данных. Какой драйвер базы данных вы используете? Можете ли вы попробовать FireDAC (если есть) или другой драйвер, чтобы проверить, сохраняется ли проблема?

Разрешение для Delphi 7 и MS SQL Server 2008 R2 (SP2)

Delphi:

    with TADOStoredProc.Create(Self) do
    try
      Connection := AConnection;
      ProcedureName := ASPName;
      Parameters.Refresh;
      Parameters.ParamByName('@XML').Value := AXML;
      try
        ExecProc;
...

MS SQL Server:

ALTER PROCEDURE dbo.StoredProcName
    @XML        NVARCHAR(MAX)
   ,@ErrMsgOut  NVARCHAR(MAX) = NULL OUT
AS BEGIN
SET NOCOUNT ON
DECLARE @RETURN INT = 0
       ,@idoc   INT

BEGIN TRY
    -- Prepare XML
    DECLARE @XML_TEXT VARCHAR(MAX)
    SET @XML_TEXT = CONVERT(VARCHAR(MAX), @XML) 
    EXEC sp_xml_preparedocument @idoc OUTPUT, @XML_TEXT

    -- Open XML
    SELECT  *
    FROM    OPENXML (@idoc, '/ServicesList/ServicesItem', 2)
    WITH
    (
        YourFields AndTypes
    )
...

Это сообщение об ошибке обычно возникает при попытке сравнить varchar(n) и текст с помощью оператора равенства (обычно в where пункт в sql, но возможно в другом месте). на MSDN была статья, в которой освещалось несколько моментов, связанных с этим.

когда вы сохраняете данные в столбце VARCHAR(N), значения физически сохраняются таким же образом. Но когда вы сохраняете его в столбце VARCHAR(MAX), за экраном данные обрабатываются как значение TEXT. Таким образом, при работе со значением VARCHAR(MAX) требуется дополнительная обработка. (только если размер превышает 8000)

Вы упомянули, что TDASchema отображает ваше новое поле как String(65536), которое, хотя раньше никогда не использовало RemObjects, я предполагаю, что где-то в его собственном коде (или в вашем) выполняется какое-то сравнение, отсюда и сообщение об ошибке.

Попробуйте использовать VARCHAR(8000) вместо MAX и посмотрите, решит ли это проблему.

Другой вариант, если вы можете найти, где в коде выполняется проверка на равенство, это попытаться сделать cast()

Другие вопросы по тегам