Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2009.08.23;
Скачать: CL | DM;

Вниз

TADOCommand + MSSQL + SP   Найти похожие ветки 

 
Барра Кабамма   (2008-11-10 15:01) [0]

Помогите понять магию и логику адо при выполнении хранимок на mssql. Исходные данные:
хранимая на сервере, три входных параметра, шесть выходных.
Сама процедура отлажена и возвращает то что нужно. Кроме того, прекрасно выполняется из под asp.net и других хранимых процедур на самом сервере.
В Д7 вызываю так:

with TADOCommand.Create(Self) do
 try
  Connection  := ADOConnection;
  CommandType := cmdStoredProc;
  CommandText := "my_procedure";
  with Parameters.AddParameter do
   begin
    Direction := pdReturnValue;
    DataType  := ftInteger;
    Name      := "@return_value";
   end;
  with Parameters.AddParameter do
   begin
    Direction := pdInput;
    DataType  := ftString;
    Size      := 20;
    Name      := "@p_cnt_num";
    Value      := ...
   end;
 ....
  with Parameters.AddParameter do
   begin
    Direction := pdInputOutput;
    DataType  := ftFloat;
    Name      := "@p_oborot_db";
   end;

Execute;

А дальше все зависит от фаз луны.

Может ругнуться на то, что ожидается параметр "@p_oborot_db который не определен.
Может ни на что не ругнуться но в половине выходных параметрах будут верные данные, в остальных либо пусто, либо неверные данные.

Если настроить ADoCommand в дизайне, то все работает как надо. Но мне необходимо создавать экземпляр динамически, или по крайней мере менять имя владельца в имени процедуры на рантайме (БД на разных серверах по разному называется), а при этом параметры установаленные в дизайнтайме говорят мне "привет".


 
GRAND ©   (2008-11-10 15:10) [1]

А че, TADOStoredProc - не кошерный компонент?


 
MsGuns ©   (2008-11-10 15:11) [2]

Не надо параметры строить вручную - это приводит к множественным ошибкам и скоропалительном выводе о глючности ADO

Я бы не рекоментдовал использовать TADOStoredProc вообще (она "удобна" в дизайне, т.к. дает возможности извлечь параметры и задать им значения визуально)
Грамотнее делать так:

with ADOCommand1 do
 try
   CommyndType := cmdStoredProc;
   CommandText := ...
   Parameters.Refresh;
   Parameters.ParamByName(..).Values := ..;
   Parameters.ParamByName(..).Values := ..;
   Execute;
 except
   ..
 end;


 
Барра Кабамма   (2008-11-10 15:18) [3]

пробовал, не помогает.

После  Parameters.Refresh ParamCount = 0


 
GRAND ©   (2008-11-10 15:19) [4]


> Не надо параметры строить вручную - это приводит к множественным
> ошибкам и скоропалительном выводе о глючности ADO


:))))))))

Я, пожалуй, помолчу...


 
MsGuns ©   (2008-11-10 15:38) [5]

>Барра Кабамма   (10.11.08 15:18) [3]
>пробовал, не помогает.

Очевидно, не так пробовал. Для указания ошибки в конкретном случае мало привести код, надо еще и саму ХП.
И, кстати, собака в именах параметров имеется в самой декларации ХП ?


 
Барра Кабамма   (2008-11-10 15:52) [6]

собака в именах параметров в хранимке есть. модификатор out для выходных тоже есть.

а сама процедура в процессе тестирования и ловли бага адо выродилась до банального присвоения выходным параметрам литеральных значений без всяких селектов.

....
set @p_oborot_db = 3.62;
set @p_oborot_cr = 4.12;
return 0;
end


 
sniknik ©   (2008-11-10 16:11) [7]

> Я, пожалуй, помолчу...
все правильно, если в десигне там где код написан борландавцами не забыли сделать рефреш параметрам/не дублировать их/правильные типы выставить и т.д. то оно и не глючит. а при ручном создании  нужно как минимум понимать что делаешь и зачем. без этого не работает/глюки, но на себя любимого никто не думает, что сам глючит....
а потому либо пользуйся готовым за тебя написанным, либо не жалуйся, а изучай то с чем работаешь.

> и ловли бага адо
лови не баги ado, а свои, и все у тебя получится.


 
Барра Кабамма   (2008-11-10 16:14) [8]

нужно как минимум понимать что делаешь и зачем

Знаешь что я первым делом сделал, когда глюк обнаружил?
Настроил все в дизайне через редактор параметров и открыл dfm.
Потом сравнил все что туда попало со своим кодом.
Все тоже самое.


 
sniknik ©   (2008-11-10 16:15) [9]

> После  Parameters.Refresh ParamCount = 0
коннект к серверу в момент рефреша есть?


 
Барра Кабамма   (2008-11-10 16:15) [10]

конечно есть


 
sniknik ©   (2008-11-10 16:17) [11]

> Все тоже самое.
а у меня нет, но всегда работает...


 
Барра Кабамма   (2008-11-10 16:26) [12]

а у меня нет, но всегда работает...

Здесь напрашивается вывод, что свойства параметров, создаваемых в рантайме должны отличаться от дизайновых и что ты знаешь как именно.
А рассказать можешь?


 
sniknik ©   (2008-11-10 16:29) [13]

> Здесь напрашивается вывод
неправильный вывод...

см. правильный код
MsGuns ©   (10.11.08 15:11) [2]
где видишь создание параметров?


 
Барра Кабамма   (2008-11-10 16:33) [14]

Ну ё-мае, мужики. Сколько можно?
Тот правильный код правилен только для него самого.
Ноль параметров у меня после рефреша. Ноль!


 
sniknik ©   (2008-11-10 16:33) [15]

кстати у тебя не все тоже самое, если бы было тоже
то было бы так
CommandText := "my_procedure;1";


 
sniknik ©   (2008-11-10 16:36) [16]

> Ну ё-мае, мужики. Сколько можно?
действительно...

> Ноль параметров у меня после рефреша. Ноль!
значит варианты
MsGuns ©   (10.11.08 15:38) [5]
> Очевидно, не так пробовал.

sniknik ©   (10.11.08 16:15) [9]
> коннект к серверу в момент рефреша есть?


 
Барра Кабамма   (2008-11-10 16:36) [17]

;1

и так тоже делал.
и два раза приседал и крек-пекс-фекс тоже говорил.


 
Барра Кабамма   (2008-11-10 16:38) [18]

sniknik ©   (10.11.08 16:15) [9]
> коннект к серверу в момент рефреша есть?


До возни с этой процедурой приложение уже успело выполнить с десяток запросов с mssql. Авторизовать пользователя, прочитать его профиль, вставить кучу записей в лог таблицу и т.д.


 
Барра Кабамма   (2008-11-10 16:46) [19]

В общем резюмирую, мужики.
Вся ваша уверенность в безгрешности делфийского адо и собственного  умения с ним работать зиждется на ограниченном жизненном опыте. Написали сотню однотипных хранимок, которые работают из под адо и все.
У меня тоже сотня хранимок работает. Одни возвращают наборы данных, другие строковые параметры.
А вот эта не работает из под делфийского адо.

И ни вы, ни я не знаете почему.


 
Барра Кабамма   (2008-11-10 16:51) [20]

Вот последний копипаст из редактора кода

with TADOCommand.Create(Self) do
 try
  Connection  := ADOConnection;
  if not ADOConnection.Connected then ADOConnection.Connected := True;   CommandType := cmdStoredProc;
  CommandText := Format("%s.dbo.GET_ACCOUNT_SALDO;1",[fDB]);
  //CommandText := Format("%s.dbo.GET_ACCOUNT_SALDO",[fDB]);
  Log("CommandText = ",CommandText);
  Parameters.Refresh;
  Log("ParamCount = ",IntToStr(ParamCount));
  for i := 0 to Pred(ParamCount) do Log(Parameters.Items[i].Name);

и в логе круглый ноль.


 
sniknik ©   (2008-11-10 17:04) [21]

> А вот эта не работает из под делфийского адо.
"эта" это собственно какая?

> И ни вы, ни я не знаете почему.
да где нам.

Log("ParamCount = ",IntToStr(ParamCount));
это что за переменная? к чему относится?


 
sniknik ©   (2008-11-10 17:12) [22]

GRAND ©
ну так как, честь ADO восстановлена? ;)
кто глючит то на самом деле? ;)))


 
Барра Кабамма ©   (2008-11-10 17:12) [23]

это что за переменная? к чему относится?

Относится к верхнему with

Log("Parameters.Count = ",IntToStr(Parameters.Count));
Log("ParamCount = ",IntToStr(ParamCount));

В логе:

10.11.2008 17:10:28 Parameters.Count =  0
10.11.2008 17:10:28 ParamCount =  0


 
sniknik ©   (2008-11-10 17:18) [24]

> Относится к верхнему with
ну так нет там такой, у верхнего with, берется системная.

> В логе:
> 10.11.2008 17:10:28 Parameters.Count =  0
сказок не рассказывай... так я тебе и поверил после [20] (хотя и до этого не очень то...).


 
Барра Кабамма ©   (2008-11-10 17:21) [25]

ты сам поменьше сказок рассказывай.
приведен код как есть и приведен лог как есть.

Parameters.Count нулевой


 
sniknik ©   (2008-11-10 17:26) [26]

> Parameters.Count нулевой
значит в твоей процедуре ПАРАМЕТРОВ НЕТ, даже @RETURN_VALUE, что както уже загадочно...


 
Барра Кабамма ©   (2008-11-10 17:27) [27]

А рефреш что с ;1 что без нее возвращает false


 
Барра Кабамма ©   (2008-11-10 17:28) [28]

значит в твоей процедуре ПАРАМЕТРОВ НЕТ, даже @RETURN_VALUE, что както уже загадочно...

Ага. А асп.нет приложение с SqlCommand читает их из космоса.


 
Барра Кабамма ©   (2008-11-10 17:31) [29]

И еще вдобавок при execute злобные марсиане мне в лог вставляют: expects parameter "@p_cnt_num", which was not supplied


 
Барра Кабамма ©   (2008-11-10 18:01) [30]

В общем слушайте опытные дивелоперы (у которых все и всегда и везде работает) и пополняйте свой небогатый жизненный опыт.

Я в начале говорил, что процедура моя самая обычная, но находится в разноименных бд на разных серверах.
А само приложение коннектится всегда к своей служебной БД и у него всегда есть гранты на объекты второй бд, которая везде по разному зовется.
Так вот.
Рефреш говорит правду только если хранимка находится в текущей базе, а если имя ей дать dbname.dbo.procedurename и сделать рефрешь, то получается тот самый эффект, который меня и всех вас поставил в тупик.

делюсь бесплатно. потому как я сегодня добрый.

ЗЫ тока не надо щас задним числом говорить, что вы это и так знали.


 
sniknik ©   (2008-11-10 19:22) [31]

> ЗЫ тока не надо щас задним числом говорить, что вы это и так знали.
не знали конечно, ты же не дал этой инфы "задним числом".

то что ты сказал, это  
> БД на разных серверах по разному называется
т.е. это понятно (имхо) - работаешь с одним сервером коннектишся к базе с одним именем, с другим к с другим.
а то что у тебя, из коннекта к одной базе вызывается процедура из другой, а в этой этой процедуры совсем нет... не говорил такого.
можно было бы по [20] догадаться, так сказать протелепатировать зачем ты там форматом в имя базы значение какой то переменной вставляешь... но извини, я как ParamCount увидел так офигел и больше не  думал на эту тему.

но это кстати не объясняет почему создание этих параметров у тебя не работает.


 
sniknik ©   (2008-11-10 19:27) [32]

> ты же не дал этой инфы "задним числом".
и даже больше того, ты это скрывал, и фальсифицировал пример
> CommandText := "my_procedure";
где здесь "xxx.xxx.my_procedure";??? показано как к родной.


 
Барра Кабамма ©   (2008-11-10 21:30) [33]

Про разные базы было в самом вопросе.

Кроме того в 20 посте было
CommandText := Format("%s.dbo.GET_ACCOUNT_SALDO",[fDB]);


 
Барра Кабамма ©   (2008-11-10 21:43) [34]

в общем ладно, проехали.
меня щас больше интересует как выйти из положения малой кровью.
базы, которые названы по разному это объективная реальность и наследие прошлого. от этого уже никуда не деться.
собственно есть выбор из трех альтернатив:
1. перетащить все объекты дефолтной бд в те разноименные экземпляры
2. использовать еще один коннект в приложении.
3. перенести процедуры в дефолтную бд и использовать там динамический sql (вообще не прикалывает такая перспектива)


 
sniknik ©   (2008-11-10 22:37) [35]

> Кроме того в 20 посте было
и там же было ParamCount, про что в [31] писал.

> собственно есть выбор из трех альтернатив:

> [31] но это кстати не объясняет почему создание этих параметров у тебя не работает.
самостоятельное создание параметров тоже должно работать, всего то убрать из "неправильного" кода в [0] глюки (раз уж "правильный" не подходит) и все.



Страницы: 1 вся ветка

Текущий архив: 2009.08.23;
Скачать: CL | DM;

Наверх




Память: 0.56 MB
Время: 0.013 c
15-1245338304
Tirael
2009-06-18 19:18
2009.08.23
скорость игрушки


15-1245914217
DVM
2009-06-25 11:16
2009.08.23
Good Quality Applications Built With Delphi


15-1245816012
Дмитрий С
2009-06-24 08:00
2009.08.23
Поиск точки


1-1212546310
San1712
2008-06-04 06:25
2009.08.23
Как добавлять строки в TListView компонент чтобы он не мигал ?


1-1212582291
i
2008-06-04 16:24
2009.08.23
проблема с tpaintbox и jpegimage