Здравствуйте.
Есть 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), чтобы вместо ??? был текст
Спасибо.
Нравится
Здравствуйте, Марина.
Попробуйте реализовать Вашу задачу по аналогии с таким примером.
Вот сама функция:
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 функции, только скриптом.
Спасибо.