Здравствуйте.

Есть sql Scalar-valued функция f, которая возвращает returns nvarchar(4000).
Я вызываю эту функцию в скрипте:

var sSQL = "select dbo.f(параметры) as message"
var Result = GetSimpleSQLResult(sSQL);

В GetSimpleSQLResult вызывается Connector.DBEngine.ExecuteCustomSQL(SQltext, Parameters);
Захватила SQL код через SQL Server Profiler

declare @p3 varchar(8000)
set @p3=' ?????? ????? ? ????? '
exec sp_executesql N' select top 1 @P1 = MESSAGE FROM f(параметры)',N'@P1 varchar(8000) OUTPUT',@p3 output
select @p3

и результат ??? знаки вместо букв

Вопрос:
можно ли изменить Connector.DBEngine.ExecuteCustomSQL(SQltext, Parameters); так чтобы параметр был
declare @p3 nvarchar(4000) а не varchar(8000), чтобы вместо ??? был текст

Спасибо.

Нравится

8 комментариев

Здравствуйте, Марина.

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

Вот сама функция:
CREATE function [dbo].[tsf_CalcBudgetFieldValueByBusinessTrip]
(@ProjectPassportID uniqueidentifier,
@CalculcatedFieldName nvarchar(50))
returns float
as
begin

declare @BudgetFieldValue float

/*to do something*/

return @BudgetFieldValue
end

function CreateSPParameters() {
return System.CreateObject('TSObjectLibrary.Parameters');
}

function CreateParam(Parameters, ParamName, ParamDataType) {
var Parameter = Parameters.CreateItem();
Parameter.Name = ParamName;
Parameter.DataType = ParamDataType;
Parameters.Add(Parameter);
return Parameter;
}

function GenNewKeyValueFromCollection(Collection, KeyValueCode) {
var ItemKeyValue;
for (var i = 0; i < Collection.Count; i++) {
ItemKeyValue = KeyValueCode + (i + 1).toString();
if (!Assigned(Collection.CoreItemsByKey(ItemKeyValue))) {
return ItemKeyValue;
}
}
return KeyValueCode;
}

function AddParameter(Parameters, ParamDataType, ParamValue, ParameterName) {
var ParamName = GenNewKeyValueFromCollection(Parameters, 'Parameter');
var Parameter = CreateParam(Parameters, ParamName, ParamDataType)
Parameter.Value = ParamValue;
if (!!ParameterName) {
Parameter.Name = ParameterName;
}
return Parameter;
}

function Calc() {
var Params = CreateSPParameters();
AddParameter(Params, pdtGUID, ProjectPassportID).Name = 'ProjectPassportID';
AddParameter(Params, pdtUnicodeString, CalculcatedFieldName).Name = 'CalculcatedFieldName';
var ResultParam = AddParameter(Params, pdtFloat, 0);
ResultParam.Name = 'BudgetFieldValue';
ResultParam.ParamType = pdtFloat;
var SQL =
'SET :BudgetFieldValue = dbo.tsf_CalcBudgetFieldValueByBusinessTrip(:ProjectPassportID, :CalculcatedFieldName)';
Connector.DBEngine.ExecuteCustomSQL(SQL, Params);
}

Здравствуйте, Алла.

Я попробовала, пока не получается. Правильно ли я все поняля ?

вот функция:

create function func_CheckNumber
(@Number as int,
@Service as int
)

returns nvarchar(4000)

as
begin

declare @msg as nvarchar(4000);
set @msg = N'';

-- логика

set @msg = N'Համար' -- текст на армянском языке, написано Номер
return @msg
end

go

скрипт:
var Params = CreateSPParameters();

AddParameter(Params, sdtInteger, '993976').Name = 'Number';
AddParameter(Params, sdtInteger, '32').Name = 'Service';

var ResultParam = AddParameter(Params, sdtUnicodeString, '');
ResultParam.Name = 'msg';
ResultParam.ParamType = sdtUnicodeString;

var sSQL = 'set :msg = [dbo].[func_CheckNumber](:Number, :Service)';

Connector.DBEngine.ExecuteCustomSQL(sSQL, Params);

var Result = Params.ItemsByName('msg').Value;

ShowInformationDialog(IsEmptyValue(Result) ? '' : Result);

-- scr_SysEnums
sdtInteger = 0x00000001;
sdtUnicodeString = 0x00000008;

SQL Server Profiler:

exec sp_executesql N'set @P1 = [dbo].[func_CheckNumber](@P2, @P3)',N'@P1 varchar(1),@P2 int,@P3 int',NULL,993976,32

Result = null, и тип @P1 varchar(1), несмотря на то, что написано ResultParam.ParamType = sdtUnicodeString;

Спасибо.

Здравствуйте, Марина!

Попробуйте после запроса на выполнение проверить, какой результат содержится в ResultParam.Value, а не в Params.ItemsByName('msg').Value.

Также проверьте результат выполнения функции в SQL Management Studio, что в этом случае возвращается.

после
Connector.DBEngine.ExecuteCustomSQL(sSQL, Params);
проверила дебаггером

ResultParam.Value
null

этот код взяла из SQL Server Profiler:
exec sp_executesql N'set @P1 = [dbo].[func_CheckNumber](@P2, @P3)',N'@P1 varchar(1),@P2 int,@P3 int',NULL,993976,32

и чтобы заработало видоизменила чуть-чуть, добавила declare @p3 as nvarchar(50), OUTPUT и varchar(1) изменила на nvarchar(50)
declare @p3 as nvarchar(50)
exec sp_executesql N'set @P1 = [dbo].[func_CheckNumber](@P2, @P3)',N'@P1 nvarchar(50) OUTPUT ,@P2 int,@P3 int',@p3 output,993976,32
select @p3

результат верен: Համար

Здравствуйте, Марина!

Уточните, пожалуйста, какую версию Terrasoft 3.X Вы используете?

Также добавьте сервисы с реализованными функциями в Terrasoft и текст SQL-функции.

Версия: 3.2.0.90

SQL функция:
create function func_CheckNumber(@Number as int,
@Service as int
)

returns nvarchar(4000)

as
begin

declare @msg as nvarchar(4000);
set @msg = N'';

-- логика

set @msg = N'Համար' -- текст на армянском, написано Номер
return @msg
end

GO

скрипт:
function edt_NumberOnExit(Control)
{
debugger

if(dlData.Dataset.State == dstInsert)
{
if(Control.DataField.DisplayValue > 0)
{
var Params = CreateSPParameters();

AddParameter(Params, sdtInteger, '993976').Name = 'Number';
AddParameter(Params, sdtInteger, '32').Name = 'Service';

var ResultParam = AddParameter(Params, sdtUnicodeString, '');
ResultParam.Name = 'msg';
ResultParam.ParamType = sdtUnicodeString;

var sSQL = 'set :msg = [dbo].[func_CheckNumber](:Number, :Service)';

Connector.DBEngine.ExecuteCustomSQL(sSQL, Params);

var Result = Params.ItemsByName('msg').Value;

ShowInformationDialog(IsEmptyValue(Result) ? '' : Result);

}
}
}

1. CreateSPParameters
2. CreateParam
3. GenNewKeyValueFromCollection
эти функции, которые Вы отправили, в точности совпадали, кроме 4. AddParameter, которую я скопировала у себя

Возможно, дело в том, что для линейки 3.Х полноценная поддержка Unicode появилась в 3.4.0. При необходимости можно попробовать обновится до 3.4.0, перезаказать лицензии (платно). Также см. обсуждение похожего случая.

Здравствуйте Александр. Обновиться вряд ли получится, вопрос решила без SQL функции, только скриптом.

Спасибо.

Показать все комментарии