Страница 1 из 2
Не одинаковое поведение Table-Valued Parameters
Добавлено: Пн 26 авг 2013 07:41
vso
Добрый день!
Есть связь TMSQuery -> TMSUpdateSQL -> TMSStoredProc.
Есть два варианта кода.
Вариант 1.
Код: Выделить всё
TMSStoredProc.PrepareSQL;
TMSStoredProc.Params.ParamByName('Table').AsTable := TMSTableData.Table;
TMSQuery.Post;
Вариант 2
Код: Выделить всё
TMSStoredProc.PrepareSQL;
TMSStoredProc.Params.ParamByName('Table').AsTable := TMSTableData.Table;
TMSStoredProc.ExecProc;
Так вот если использовать вариант 1, то возникает ошибка. SQL возвращает "Недопустимый тип параметра".
Если же использовать Вариант 2, то все работает, но тогда состояние TMSQuery, после выполнения TMSStoredProc так же в dsInsert или dsEdit.
А надо бы чтобы изменилось и отработало свойство Refresh.
Подскажите как быть?
Re: Не одинаковое поведение Table-Valued Parameters
Добавлено: Вт 27 авг 2013 08:28
vso
Попробовал перенести вызов процедуры в TMSQuery, написав:
Код: Выделить всё
exec spAddVolume :LINK_REPORTS READONLY, :ID_VOLUME, :NUMBER, :TITLE, :VERSION, :REF_TYPE, :SHORTNAME, :LONGNAME, :REF_BUILDING, :NUM_REVISION
но получаю ошибку:
Код: Выделить всё
Возвращающий табличное значение параметр "@P1" должен быть объявлен как READONLY.
хотя в процедуре все прописано:
Код: Выделить всё
ALTER PROCEDURE [dbo].[spAddVolume]
@LINK_REPORTS dbo.LinkReports READONLY,
@ID_VOLUME INT,
@NUMBER VARCHAR(50),
@TITLE VARCHAR(510),
@VERSION INT,
@REF_TYPE INT,
@SHORTNAME VARCHAR(255),
@LONGNAME VARCHAR(255),
@REF_BUILDING INT,
@NUM_REVISION VARCHAR(20)
AS
Re: Не одинаковое поведение Table-Valued Parameters
Добавлено: Вт 27 авг 2013 11:31
Alexp
Добрый день,
Пожалуйста пришлите небольшое приложение воспроизводящее проблему на alexp*devart*com, а также скрипты для создания объектов БД.
P.S. При Вызове TMSStoredProc.ExecProc связанный с этим компонентом DataSet не изменит своего состояния, состояние меняться только после вызова Post
Re: Не одинаковое поведение Table-Valued Parameters
Добавлено: Чт 29 авг 2013 12:19
Alexp
Добрый день,
Спасибо, я получил Ваш пример. Это корректное поведение, так как если для добавления/обновления данных в MSQuery используется хранимая процедура то ее параметры должны совпадать с полями DataSet. Для решения данной проблемы, вы можете устанавливать значения данного параметра в методе BeforeUpdateExecute например
Код: Выделить всё
procedure TForm1.MSQuery1BeforeUpdateExecute(Sender: TCustomMSDataSet;
StatementTypes: TStatementTypes; Params: TMSParams);
begin
Params.ParamByName('LINK_REPORTS').AsTable := MSTableData1.Table;
end;
в этом случае ошибки не возникнет, и DataSet изменит свое состояние
Re: Не одинаковое поведение Table-Valued Parameters
Добавлено: Чт 29 авг 2013 15:21
vso
Спасибо за ответ, но не работает!
Все равно пишет ошибку - "Недопустимый тип параметра"
Re: Не одинаковое поведение Table-Valued Parameters
Добавлено: Чт 29 авг 2013 15:48
Alexp
Добрый день,
Если в Вашем примере добавить следующий метод
Код: Выделить всё
procedure TForm3.MSQuery1BeforeUpdateExecute(Sender: TCustomMSDataSet;
StatementTypes: TStatementTypes; Params: TMSParams);
var
i : integer;
begin
MSTableData1.Active := true;
for i := 0 to CheckListBox1.Count - 1 do MSTableData1.AppendRecord([CheckListBox1.Items.Names[i],Integer(CheckListBox1.State[i])]);
Params.ParamByName('Link_Reports').AsTable := MSTableData1.Table;
end;
а в методе BitBtn1Click оставить только вызов Post, то никаких ошибок не возникает, пожалуйста попробуйте внести описанные изменения и проверить результат
Re: Не одинаковое поведение Table-Valued Parameters
Добавлено: Пт 30 авг 2013 06:22
vso
Добрый день!
Сделал как Вы указали, и на своем проекте и на тестовом - результат один и тот же.
И вот он в картинках:
Re: Не одинаковое поведение Table-Valued Parameters
Добавлено: Пт 30 авг 2013 07:45
Alexp
Добрый день,
Вам необходимо вместо Вашего кода, вставить в метод BeforeUpdateExecute приведенный мной код в предыдущем посте, тогда ошибки не возникнет
Re: Не одинаковое поведение Table-Valued Parameters
Добавлено: Пт 30 авг 2013 13:19
vso
Alexp писал(а):Добрый день,
Вам необходимо вместо Вашего кода, вставить в метод BeforeUpdateExecute приведенный мной код в предыдущем посте, тогда ошибки не возникнет
Действительно я был замечен во не внимательности, но простая операция копирования Вашего кода и вставки его в тестовый проект не принесла успеха. Ошибка все таже
Re: Не одинаковое поведение Table-Valued Parameters
Добавлено: Пт 30 авг 2013 17:09
Alexp
Добрый день,
Ниже приведен небольшой тестовый консольный пример, демонстрирующий необходимое Вам поведение, пожалуйста проверьте его работоспособность
Код: Выделить всё
program Project1;
{$APPTYPE CONSOLE}
uses
SysUtils,
DB,
MSAccess,
DBAccess,
ActiveX;
type
TMyClass = class
private
MSConnection: TMSConnection;
MSQuery: TMSQuery;
MSUpdateSQL: TMSUpdateSQL;
MSStoredProc: TMSStoredProc;
MSTableData: TMSTableData;
public
procedure BeforeUpdateExecute(Sender: TCustomMSDataSet;
StatementTypes: TStatementTypes; Params: TMSParams);
procedure test;
end;
var
MyClass: TMyClass;
{ MyClass }
procedure TMyClass.BeforeUpdateExecute(Sender: TCustomMSDataSet;
StatementTypes: TStatementTypes; Params: TMSParams);
begin
MSTableData.Open;
MSTableData.AppendRecord(['',1]);
Params.ParamByName('Link_Reports').AsTable := MSTableData.Table;
end;
procedure TMyClass.test;
begin
CoInitializeEx(nil, COINIT_MULTITHREADED);
try
MSConnection := TMSConnection.Create(nil);
try
MSConnection.Server := 'OATP';
MSConnection.Username := 'sa';
MSConnection.Password := 'bn1a90';
MSConnection.Database := 'test';
MSConnection.Connect;
MSQuery := TMSQuery.Create(nil);
try
MSQuery.Connection := MSConnection;
MSQuery.SQL.Text := 'select * from volume';
MSQuery.BeforeUpdateExecute := BeforeUpdateExecute;
MSQuery.Options.StrictUpdate := False;
MSUpdateSQL := TMSUpdateSQL.Create(nil);
try
MSQuery.UpdateObject := MSUpdateSQL;
MSStoredProc := TMSStoredProc.Create(nil);
try
MSStoredProc.Connection := MSConnection;
MSStoredProc.StoredProcName := 'spAddVolume';
MSUpdateSQL.InsertObject := MSStoredProc;
MSQuery.Open;
MSQuery.Insert;
MSQuery.FieldByName('NUMBER').AsInteger := 1;
MSTableData := TMSTableData.Create(nil);
try
MSTableData.Connection := MSConnection;
MSTableData.TableTypeName := 'LinkReports';
MSQuery.Post;
finally
MSTableData.Free;
end;
finally
MSUpdateSQL.InsertObject := nil;
MSStoredProc.Free;
end;
finally
MSQuery.UpdateObject := nil;
MSUpdateSQL.Free;
end;
finally
MSQuery.Free;
end;
finally
MSConnection.Free;
end;
finally
CoUninitialize;
end;
end;
begin
MyClass := TMyClass.Create;
try
MyClass.test;
finally
MyClass.Free;
end;
end.
Re: Не одинаковое поведение Table-Valued Parameters
Добавлено: Пн 02 сен 2013 08:23
vso
Приложение выдает такую ошибку:
Re: Не одинаковое поведение Table-Valued Parameters
Добавлено: Вт 03 сен 2013 10:50
AndreyZ
Я не могу повторить данную ошибку. Укажите пожалуйста точные версии SQL Server сервера и клиента которые Вы используете. Вы можете найти их на закладке Info редактора компонента TMSConnection.
Re: Не одинаковое поведение Table-Valued Parameters
Добавлено: Вт 03 сен 2013 11:02
vso
Microsoft SQL Server: 10.50.4000
Microsoft SQL Server Native Client 10.0: 10.50.4000.0
Re: Не одинаковое поведение Table-Valued Parameters
Добавлено: Вт 03 сен 2013 11:33
AndreyZ
К сожалению я по прежнему не могу повторить ошибку. Попробуйте запустить это консольное приложение из Delphi XE2 в режиме отладки и определить конкретную строчку кода которая приводит к генерации исключения.
Re: Не одинаковое поведение Table-Valued Parameters
Добавлено: Вт 03 сен 2013 13:53
vso
К сожалению я по прежнему не могу повторить ошибку. Попробуйте запустить это консольное приложение из Delphi XE2 в режиме отладки и определить конкретную строчку кода которая приводит к генерации исключения.