Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Базы";
Текущий архив: 2009.08.23;
Скачать: [xml.tar.bz2];

Вниз

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;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.54 MB
Время: 0.005 c
15-1244032296
Игорь Шевченко
2009-06-03 16:31
2009.08.23
сделать для формы (фрейма, WinControl) аналог Begin/EndUpdatе


15-1245702601
Юрий
2009-06-23 00:30
2009.08.23
С днем рождения ! 23 июня 2009 вторник


15-1245612165
Холивар
2009-06-21 23:22
2009.08.23
IDirect3DTexture9 самый простой способ копирования данных с HDC.


15-1245756951
tesseract
2009-06-23 15:35
2009.08.23
FireBird прошёл в финалисты Community choice


15-1245486265
TCrash
2009-06-20 12:24
2009.08.23
Органайзер/календарь





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский