Вот контекст для библиотеки OpenSource:
- Я вызываю библиотеку OleDB напрямую из неуправляемого кода (Delphi);
- Я связываю параметры, создавая
IAccessor
в ICommandText
экземпляр OleDB; - У меня нет проблем с простыми типами, такими как
DBTYPE_I8
или DBTYPE_DATE
; - Я хотел бы связать текстовые параметры как
DBTYPE_WSTR
type, т.е. всегда как Unicode.
Проблема заключается в том, что для типа DBTYPE_WSTR
я получаю ошибку OLEDB Error 80040E1D (DB_E_UNSUPPORTEDCONVERSION), «Запрошенное преобразование не поддерживается», когдаCommand.Execute
называется.
Конечно, я пробовал с или без DBTYPE_BYREF
макета данных (т.е. установив FIELDTYPE2OLEDB[ftUTF8]=DBTYPE_WSTR or DBTYPE_BYREF
в приведенном ниже коде и изменив макет): та же проблема ..работает с DBTYPE_WSTR
, но не с DBTYPE_STR
.
Но если я изменю тип параметра с DBTYPE_WSTR
на DBTYPE_STR
(т. е. установим FIELDTYPE2OLEDB[ftUTF8]=DBTYPE_STR or DBTYPE_BYREF
в приведенном ниже коде), команда будет выполнена безлюбая проблема.Но вместо этого я хотел бы использовать DBTYPE_WSTR
wType, чтобы гарантировать, что ни один символ не будет потерян из-за текущего набора символов Ansi.
На самом деле, я могу получить любые данные IRowSet
без проблем, как DBTYPE_WSTR
, но я не могу связать значение параметра с DBTYPE_WSTR
.
Я подключен к экземпляру Microsoft SQL Server 2008 R2.Код работает без параметров в запросе SQL или с параметрами int или float, но не с параметрами TEXT.
Вот основной пример кода:
Query.Execute('select * from Person.Address where AddressLine1 like ?;',true,['% Drive']);
AddressLine1
столбец определен как nvarchar(60)
в AdventureWorks2008R2 эталонной базе данных, поэтому он должен сопоставляться с DBTYPE_WSTR
, согласно официальной документации MSDN .
Полный исходный код соответствующего модуля доступен из нашего репозитория исходного кода .Код в методе TOleDBStatement.Execute
, как таковой:
const
PARAMTYPE2OLEDB: array[TSQLDBParamInOutType] of DBPARAMIO = (
DBPARAMIO_INPUT, DBPARAMIO_OUTPUT, DBPARAMIO_INPUT or DBPARAMIO_OUTPUT);
FIELDTYPE2OLEDB: array[TSQLDBFieldType] of DBTYPE = (
DBTYPE_EMPTY, DBTYPE_NULL, DBTYPE_I8, DBTYPE_R8, DBTYPE_CY, DBTYPE_DATE,
DBTYPE_WSTR or DBTYPE_BYREF, DBTYPE_BYTES or DBTYPE_BYREF);
(...)
OleDBCheck((fSession as IDBCreateCommand).
CreateCommand(nil,IID_ICommandText,ICommand(fCommand)));
fCommand.SetCommandText(DBGUID_DEFAULT,pointer(Utf8DecodeToRawUnicodeUI(aSQL)));
P := pointer(fParams);
SetLength(fParamBindings,fParamCount);
B := pointer(fParamBindings);
for i := 1 to fParamCount do begin
B^.iOrdinal := i; // parameter index (starting at 1)
B^.eParamIO := PARAMTYPE2OLEDB[P^.VInOut]; // parameter direction
B^.wType := FIELDTYPE2OLEDB[P^.VType]; // parameter data type
// set additional fields
case P^.VType of
ftInt64, ftDouble, ftCurrency, ftDate: begin
// those types match the VInt64 binary representation :)
B^.cbMaxLen := sizeof(Int64);
B^.dwPart := DBPART_VALUE;
B^.obValue := PAnsiChar(@P^.VInt64)-pointer(fParams);
end;
ftUTF8, ftBlob: begin
// sent as DBTYPE_BYREF mapping directly the VRawByteString content
B^.dwPart := DBPART_VALUE or DBPART_LENGTH or DBPART_STATUS;
B^.obValue := PAnsiChar(@P^.VRawByteString)-pointer(fParams);
B^.cbMaxLen := sizeof(Pointer);
Len := length(P^.VRawByteString);
if P^.VType=ftUTF8 then
Len := Len shr 1; // expect length in WideChar count, excluding #0
P^.VInt64 := Len; // store length in unused VInt64 property
B^.obLength := PAnsiChar(@P^.VInt64)-pointer(fParams);
B^.obStatus := B^.obLength+4;
end;
end;
inc(P);
inc(B);
end;
OleDBConnection.OleDBCheck((fCommand as IAccessor).CreateAccessor(
DBACCESSOR_PARAMETERDATA,fParamCount,Pointer(fParamBindings),0,
fDBParams.HACCESSOR,nil));
OleDBConnection.OleDBCheck(fCommand.Execute(
nil,IID_IRowset,fDBParams,nil,@fRowSet),ParamsStatus);
Поэтому мой вопрос:
Как связать параметр B^.wType=DBTYPE_WSTR
для столбца nvarchar()
без ошибки DB_E_UNSUPPORTEDCONVERSION в fCommand.Execute
.
Я подозреваю, что есть какое-то свойство для установки экземпляра ISession
или ICommand
или какой-либо флаг / опция для установки, но я не былсмог найти какой из документации MSDN.Любая помощь приветствуется!