Мой код Delphi открывает TFDQuery
(FireDAC), затем открывает TClientDataSet
, подключенный к нему через TDataSetProvider
:
ClientDataSetData.Close;
with QueryData do
begin
Close;
SQL.Clear;
SQL.Add(ASelectSQL);
Open;
end;
ClientDataSetData.Open;
ASelectSQL
содержит этот SQL:
SELECT TT_NIV_ID,
TT_NIV,
REPLACE(TT_NIV_NAME, '|', '!') as TT_NIV_NAME2
FROM TT_SYS_PRJ_NIV
ClientDataSetData.Open
выдает недостаточную ошибку памяти в наборе данных с записями 42200.
Если я проверяю данные результата (в коде Delphi), я вижу, что TT_NIV_NAME2
- это строка длины8000!Из документации REPLACE () :
Если string_expression не относится к типу varchar (max) или nvarchar (max), REPLACE усекает возвращаемое значение до 8000 байт
... так что, похоже, это происходит;не только усечение, но и установка типа результата.
TT_NIV_NAME
- это VARCHAR(50)
, поэтому быстрое решение состоит в том, чтобы изменить SQL на
SELECT TT_NIV_ID,
TT_NIV,
CAST(REPLACE(TT_NIV_NAME, '|', '!') as VARCHAR(50)) as TT_NIV_NAME2
FROM TT_SYS_PRJ_NIV
, но это определяется пользователемSQL, который я не могу контролировать.В следующий раз, когда он может запустить с REPLACE
что-то еще ... Я бы предпочел универсальное решение.
Могу ли я что-нибудь сделать с кодом Delphi (Настройки TClientDataset
или TFDQuery
или TFDConnection
?), Которые предотвращают такое высокое использование памяти?
И, честно говоря, почему бы REPLACE
пришел к выводу, что "string_expression не относится к типу varchar (max) ", когда TT_NIV_NAME
является VARCHAR(50)
?
Примечания:
- Протестировано с несколькими драйверами сервера SQL - это не проблема драйвера.
TFDConnection
имеет FetchOptions.Mode := fmAll
и FetchOptions.Items := FetchOptions.Items - [fiMeta]
;fmAll
должно остаться *, и не вычитать fiMeta
не имеет значения. - Связано [1] , но здесь
string_expression
длиннее 8000, или [2] , где string_expression
не относится к типу varchar(max)
, но оба не применимы к моим данным SQL. - Delphi Tokyo 10.2.3 с использованием FireDAC против SQL Server 2012, приложение Win32запуск под Win7 или Win10
* .. для предотвращения известной ошибки hstmt в среде, где установлены только самые базовые драйверы SQL Server;и в любом случае в моем тестовом приложении это не имеет значения.