Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Sp & Ado

460
15 августа 2003 года
Berg
261 / / 27.03.2003
Добрый день, уважаемые. Вопрос дурацкий, но все-таки: как правильно вызвать такую ХП посредством TADOStoredProc:

CREATE PROCEDURE dbo.CreateNewEstimate
@Number varchar(50),
@DocID int OUTPUT,
@ContractID int = NULL,
@ObjID int = NULL
AS
SET NOCOUNT ON
INSERT INTO Estimate(ObjectId, ContractId, Number)
VALUES (@ObjID, @ContractID, @Number)

SELECT @DocID = SCOPE_IDENTITY()
SET NOCOUNT OFF
GO

Из-за того, что у нее два параметра по умолчанию, Builder ругается...Я создаю параметры run-time примерно так:
Proc->Parameters->CreateParameter("", ftString, pdInput, Number.Length(), Number);

Если не создавать для двух последних параметров ХП параметры ADOStoredProc, то все ОК. Если создавать их в случае, когда они не NULL и передавать, то тоже все ОК. В общем как написать универсальный код вызова ХП? Типа можно креатить параметры только при необходимости, но как тогда передать функции ObjID при отсутствии ContractID?
В общем, подза#$%ся я что-то. Ведь должно быть все очень просто...
Спасибо за внимание.

Работает только если
358
15 августа 2003 года
moonmike
423 / / 18.10.2002
Серег, у меня в конструкторе DataModul'я есть такие строки:
Код:
for(int i = 0; i < this->ComponentCount; i++)
    {
    AnsiString S = ClassName(Components->ClassType());
    if(S == "TADOStoredProc")
        {
        ((TADOStoredProc*)Components)->Active = false;
        ((TADOStoredProc*)Components)->Connection = (TADOConnection*)AC;
        ((TADOStoredProc*)Components)->Parameters->Refresh();
        }
    else if(S == "TClientDataSet")
        {
        ((TClientDataSet*)Components)->Close();
        ((TClientDataSet*)Components)->Filtered = false;
        }
    }

Вот эта строка:

((TADOStoredProc*)Components)->Parameters->Refresh();
Как раз и выполняет корректное создание всех параметров TADOStoredProc.
460
15 августа 2003 года
Berg
261 / / 27.03.2003
Спасибо, не особо понял что же именно рефрештся...По F1 какая-то обтекаемая фраза про "актуальность" параметров.

В общем как тогда уже делается потом присваивание им значений? Например, простое
Proc->Parameters->Items[0]->Value = Number;

вызвало ошибку несоответствия типов...
Number имеет тип AnsiString

Мне бы что-нибуть типа
Proc->Parameters->Items[2]->Clear, чтобы задать параметру NULL-значение. Для полей данный есть такой метод.
358
15 августа 2003 года
moonmike
423 / / 18.10.2002
Цитата:
Originally posted by Berg
Спасибо, не особо понял что же именно рефрештся...По F1 какая-то обтекаемая фраза про "актуальность" параметров.

В общем как тогда уже делается потом присваивание им значений? Например, простое
Proc->Parameters->Items[0]->Value = Number;

вызвало ошибку несоответствия типов...
Number имеет тип AnsiString

Мне бы что-нибуть типа
Proc->Parameters->Items[2]->Clear, чтобы задать параметру NULL-значение. Для полей данный есть такой метод.


Серег, первое, никогда не работай через индексы коллекций. Почему? Да потому, что поменяешь потом порядок следования параметров и будет попа. Работай через:
Proc->Parameters->ParamByName("@MyParam")->Value = Number;
У меня вся работа так построена. Да, действительно, по сравнению с обращением по индексу, есть задержка на вызове по имени, но она ничтожно мала, так что ради стабильности кода на это можно наплевать.
Далее, для обнуления значения параметра следует использовать следующую конструкцию:
Proc->Parameters->ParamByName("@MyParam")->Value = Null;
А фраза про актуальность параметров означает что их объявление всегда будет актуальным. Допустим была у тебя ХП с параметром типа int. Создал ты под нее в коде параметр. А потом в ХП тип параметра сменил на bigint. Так вот с твоим подходом придется лезть в код и везде где ты этот параметр создавал менять объявление. А с Refresh ничего этого делать не надо будет.

460
18 августа 2003 года
Berg
261 / / 27.03.2003
Цитата:
Originally posted by moonmike

Серег, первое, никогда не работай через индексы коллекций. Почему? Да потому, что поменяешь потом порядок следования параметров и будет попа. Работай через:
Proc->Parameters->ParamByName("@MyParam")->Value = Number;
Далее, для обнуления значения параметра следует использовать следующую конструкцию:
Proc->Parameters->ParamByName("@MyParam")->Value = Null;



Спасибо, moonmike, но что-то все равно мало получается...При таком раскладе:
Proc->Parameters->ParamByName("@MyParam")->Value = Null
ХП стабильно получает 0 вместо NULL и генерятся ошибки FK (что естественно ввиду отсутствия в таблицах ID == 0)

Пока что думаю поставить в ХП
IF @param=0 SET @param = NULL, но выглядит кривовато...:-)

358
18 августа 2003 года
moonmike
423 / / 18.10.2002
Не работает так:
Цитата:
Originally posted by Berg

Proc->Parameters->ParamByName("@MyParam")->Value = Null


Попробуй так:
Proc->Parameters->ParamByName("@MyParam")->Value = "";

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог