Обсуждение возникших проблем, предложений и ошибок SDAC компонентов
-
vso
- Сообщения: 39
- Зарегистрирован: Чт 24 янв 2013 11:08
Сообщение
vso » Пн 26 авг 2013 07:41
Добрый день!
Есть связь 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.
Подскажите как быть?
-
vso
- Сообщения: 39
- Зарегистрирован: Чт 24 янв 2013 11:08
Сообщение
vso » Вт 27 авг 2013 08:28
Попробовал перенести вызов процедуры в 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
-
Alexp
- Devart Team
- Сообщения: 349
- Зарегистрирован: Пн 27 дек 2010 10:34
Сообщение
Alexp » Вт 27 авг 2013 11:31
Добрый день,
Пожалуйста пришлите небольшое приложение воспроизводящее проблему на alexp*devart*com, а также скрипты для создания объектов БД.
P.S. При Вызове TMSStoredProc.ExecProc связанный с этим компонентом DataSet не изменит своего состояния, состояние меняться только после вызова Post
-
Alexp
- Devart Team
- Сообщения: 349
- Зарегистрирован: Пн 27 дек 2010 10:34
Сообщение
Alexp » Чт 29 авг 2013 12:19
Добрый день,
Спасибо, я получил Ваш пример. Это корректное поведение, так как если для добавления/обновления данных в MSQuery используется хранимая процедура то ее параметры должны совпадать с полями DataSet. Для решения данной проблемы, вы можете устанавливать значения данного параметра в методе BeforeUpdateExecute например
Код: Выделить всё
procedure TForm1.MSQuery1BeforeUpdateExecute(Sender: TCustomMSDataSet;
StatementTypes: TStatementTypes; Params: TMSParams);
begin
Params.ParamByName('LINK_REPORTS').AsTable := MSTableData1.Table;
end;
в этом случае ошибки не возникнет, и DataSet изменит свое состояние
-
vso
- Сообщения: 39
- Зарегистрирован: Чт 24 янв 2013 11:08
Сообщение
vso » Чт 29 авг 2013 15:21
Спасибо за ответ, но не работает!
Все равно пишет ошибку - "Недопустимый тип параметра"
-
Вложения
-
- Это передаваемые параметры
- 2.jpg (220.83 КБ) 16068 просмотров
-
- Это ошибка
- 1.jpg (231.92 КБ) 16068 просмотров
-
Alexp
- Devart Team
- Сообщения: 349
- Зарегистрирован: Пн 27 дек 2010 10:34
Сообщение
Alexp » Чт 29 авг 2013 15:48
Добрый день,
Если в Вашем примере добавить следующий метод
Код: Выделить всё
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, то никаких ошибок не возникает, пожалуйста попробуйте внести описанные изменения и проверить результат
-
vso
- Сообщения: 39
- Зарегистрирован: Чт 24 янв 2013 11:08
Сообщение
vso » Пт 30 авг 2013 06:22
Добрый день!
Сделал как Вы указали, и на своем проекте и на тестовом - результат один и тот же.
И вот он в картинках:
-
Вложения
-
- Та же ошибка
- 1.jpg (235.54 КБ) 16064 просмотра
-
- Код как у Вас
- 2.jpg (229.12 КБ) 16064 просмотра
-
Alexp
- Devart Team
- Сообщения: 349
- Зарегистрирован: Пн 27 дек 2010 10:34
Сообщение
Alexp » Пт 30 авг 2013 07:45
Добрый день,
Вам необходимо вместо Вашего кода, вставить в метод BeforeUpdateExecute приведенный мной код в предыдущем посте, тогда ошибки не возникнет
-
vso
- Сообщения: 39
- Зарегистрирован: Чт 24 янв 2013 11:08
Сообщение
vso » Пт 30 авг 2013 13:19
Alexp писал(а):Добрый день,
Вам необходимо вместо Вашего кода, вставить в метод BeforeUpdateExecute приведенный мной код в предыдущем посте, тогда ошибки не возникнет
Действительно я был замечен во не внимательности, но простая операция копирования Вашего кода и вставки его в тестовый проект не принесла успеха. Ошибка все таже
-
Alexp
- Devart Team
- Сообщения: 349
- Зарегистрирован: Пн 27 дек 2010 10:34
Сообщение
Alexp » Пт 30 авг 2013 17:09
Добрый день,
Ниже приведен небольшой тестовый консольный пример, демонстрирующий необходимое Вам поведение, пожалуйста проверьте его работоспособность
Код: Выделить всё
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.
-
vso
- Сообщения: 39
- Зарегистрирован: Чт 24 янв 2013 11:08
Сообщение
vso » Пн 02 сен 2013 08:23
Приложение выдает такую ошибку:
-
Вложения
-
- 1.jpg (189.6 КБ) 16047 просмотров
-
AndreyZ
- Devart Team
- Сообщения: 328
- Зарегистрирован: Чт 08 сен 2011 13:18
Сообщение
AndreyZ » Вт 03 сен 2013 10:50
Я не могу повторить данную ошибку. Укажите пожалуйста точные версии SQL Server сервера и клиента которые Вы используете. Вы можете найти их на закладке Info редактора компонента TMSConnection.
-
vso
- Сообщения: 39
- Зарегистрирован: Чт 24 янв 2013 11:08
Сообщение
vso » Вт 03 сен 2013 11:02
Microsoft SQL Server: 10.50.4000
Microsoft SQL Server Native Client 10.0: 10.50.4000.0
-
AndreyZ
- Devart Team
- Сообщения: 328
- Зарегистрирован: Чт 08 сен 2011 13:18
Сообщение
AndreyZ » Вт 03 сен 2013 11:33
К сожалению я по прежнему не могу повторить ошибку. Попробуйте запустить это консольное приложение из Delphi XE2 в режиме отладки и определить конкретную строчку кода которая приводит к генерации исключения.
-
vso
- Сообщения: 39
- Зарегистрирован: Чт 24 янв 2013 11:08
Сообщение
vso » Вт 03 сен 2013 13:53
К сожалению я по прежнему не могу повторить ошибку. Попробуйте запустить это консольное приложение из Delphi XE2 в режиме отладки и определить конкретную строчку кода которая приводит к генерации исключения.