Конференция "Базы" » ADO и MS SQL - посоветуйте хорошую ссылку [MSSQL]
 
  • Anatoly Podgoretsky © (09.09.08 13:53) [40]
    > kaif  (09.09.2008 13:27:36)  [36]

    Не разбирался, но кажется в рамках транзакции, если задана в транзакции.
    И в рамках сессии если задано на уровне AdoConnection.

    Подумай также насчет прямой работе с АДО, но через компоненты, а не интерфейсы, можно получить интерсные результаты.
  • sniknik © (09.09.08 13:56) [41]
    > А что я корявого выдал?
    имя поля более принято задавать через as,  а левая часть выражения логически соответствует то чему присваивается.
    хотя это и не смертельно, т.к. синтаксически верны оба варианта.

    kaif ©   (09.09.08 12:29) [33]
    > зачем мне тебе врать
    меня это всегда удивляло (это вообще а не только в тебе), вроде бы и не зачем, вроде и нужно только спрашивающему но тем не менее врут, скрывают исходную инфу, недоговаривают, не следуют советам, мало того даже не проверяют сказанное по их проблеме... т.е. ведут себя неадекватно (имхо), зачем тогда спрашивали?

    > я впредь конкретно для тебя буду приводить код, специально переписанный для тебя  в форме типа:

    > MyCommand = TADOCommans.Create(nil)
    > try
    >   MyCommand.Connection := ...
    >   и так далее, включая добавление параметров и всего такого
    >   MyCommand.Execute;
    > finally
    >   MyCommand.Free;
    > end
    если буквально так, то это будет вранье "в волшебных пузырьках". говоря что ты чтото сделал и показывая подобный код который ничего этого не подтверждает, а пропускает...

    ну, как я понял, ты так и не удосужился сделать правильно, с установкой типа параметра...
    принял другой вариант "обходной и нестандартный" (хотя что такого нестандартного в возврате рекордсета непонятно), ну, твое дело, работают оба варианта.
  • kaif © (09.09.08 14:14) [42]
    2 Ega23 ©   (09.09.08 13:47) [38]
    Я попробовал.

    Но я не знаю, не происходит ли каких-нибудь неявных автокоммитов после команд DDL.

    Я открыл два отдельных окна запросов в Microsoft SQL Server Management Studio Express. Похоже, что это две разные сессии (хотя я могу ошибаться). В каждой я вижу, что set nocount Работает независимо.
  • Ega23 © (09.09.08 14:17) [43]

    > имя поля более принято задавать через as,  а левая часть
    > выражения логически соответствует то чему присваивается.
    > хотя это и не смертельно, т.к. синтаксически верны оба варианта.


    Исключительно дело привычки. Мне, в принципе, пофиг как писать:
    Select Result = @Result
    Select @Result as Result
    Select @Result Result



    В MSSQL все три варианта равнозначны.
    Просто так привык.
  • kaif © (09.09.08 14:31) [44]
    2 sniknik ©   (09.09.08 13:56) [41]

    Блин. Вы меня меня задолбали.
    Я сейчас специально для Вас, сударь, напишу код со всемия явными присвоениями, и который НЕ РАБОТАЕТ ТАК, КАК ВЫ НАСТАИВАЕТЕ ЧТО ТИПА ОБЯЗАН РАБОТАТЬ.

    А Вы мне, милостивый государь, покажете, где в нем ошибка.

    Если же не покажете, то я смею заявить, что Вы, сударь, - бесчестный человек и хам, так как обвиняете меня во вранье, не имея на то никаких оснований.

    Вот код. Специально для тупых.

    procedure TSimpleReferenceForm.Button1Click(Sender: TObject);
    var
     P: TParameter;
    begin
     with TADOCommand.Create(nil) do
     try
       Connection := MainData.Connection;

       P := Parameters.AddParameter;
       P.DataType := ftString;
       P.Direction := pdInput;
       P.Name := 'NAME';

       P := Parameters.AddParameter;
       P.DataType := ftInteger;
       P.Direction := pdOutput;
       P.Name := 'ID';

       CommandText :=
          'INSERT INTO GOODS(GOOD_NAME) VALUES (:NAME)'#13#10+
          'SELECT :ID = SCOPE_IDENTITY()';

       Parameters.ParamByName('NAME').Value := 'Дядя Вася';

       Execute;
       if Parameters.FindParam('ID') = nil then
         ShowMessage('Параметр не найден')
       else if Parameters.ParamByName('ID').Value = Null then
         ShowMessage('Параметр вернул значение NULL. sniknik © зря упорствует в свеой неправоте')
       else
         ShowMessage('Происходит нечто третье');
     finally
       Free;
     end;
    end;



    Догадатесь с трех раз, какое сообщение он у меня вывел?
  • sniknik © (09.09.08 14:42) [45]
    Anatoly Podgoretsky ©   (09.09.08 13:41) [37]
    > FixedChar <> NVarChar(WideString) = Char ...
    > ...
    не сталкивался, юникод не использую, только пробовал один раз, както. т.что ничего сказать не могу.

    > AutoInc <> Integer, хотя бы потому что он ReadOnly и не только Integer
    а вот тут непонятно, как типом AutoInc может быть параметр? насколько понимаю автоинкремент это исключительно свойство поля таблицы или в старших версиях mssql (> 2000, больше всего с ним работаю) уже появились переменные такого типа?
    если же речь не о параметрах, а именно о поле, то инфа о его типе запрашивается от сервера через провайдера, и результаты действительно разные, тип от jet позволяет даже редактировать это поле в режиме ltBatchOptimistic, а вот от mssql нет, т.е. это не свойство обертки.
  • sniknik © (09.09.08 14:44) [46]
    > Вот код. Специально для тупых.
    специально повторить что тип параметрам (да и всему другому) надо задавать после инициализации, а не до? ;)
    внесение запроса переинициализирует все и вся... объяснял вроде почему.
  • sniknik © (09.09.08 14:48) [47]
    > что Вы, сударь, - бесчестный человек и хам, так как обвиняете меня во вранье, не имея на то никаких оснований.
    нет, только хам. и основания есть. говоришь одно код показываешь другой (или не показываешь, предлагая верить на слово, а результаты описываешь нестыкующиеся даже с тем что  есть в исходных данных).

    кстати приведенный код, это именно то к чему следует стремится при описании проблемы.
  • sniknik © (09.09.08 14:51) [48]
    еще кстати, создавать параметры не нужно (по умолчанию ParamCheck true), только инициализировать. созданием ты добавишь новых а значения будут браться из старых... т.е. не исправив этот глюк, перенос ничего не поменяет.
  • Ega23 © (09.09.08 14:55) [49]

    > Вот код. Специально для тупых.


    Ашот, ты реально неправ. В коде - косяк на косяке.

    1. Если стоит DataSet.paramCheck = True то
     1.1. Если на момент задания коннекшена он (коннекшн) подключенный (Connected=True) то блок инициализация первого параметра нафиг не нужна.
     1.2. Если коннект не подключен, либо ParamCheck=False, то надо инициализировать.

    2. В любом случае, инициализацию параметров надо делать ПОСЛЕ задавания CommandText.

    З.Ы. Я бы на твоем месте извинился.
  • kaif © (09.09.08 14:58) [50]
    А вот решение проблемы. Если бы  sniknik © вместо того чтобы упрекать меня во вранье сам не врал о том, будто он знает, зачем устанавливать значение Direction рантайм, то вопрос был бы исчерпан еще вчера.

    var
     DirectionNames: array [0..4] of string = ('pdUnknown', 'pdInput', 'pdOutput', 'pdInputOutput', 'pdReturnValue');

    procedure TSimpleReferenceForm.Button1Click(Sender: TObject);
    var
     P: TParameter;
    begin
     with TADOCommand.Create(nil) do
     try
       Connection := MainData.Connection;

       P := Parameters.AddParameter;
       P.DataType := ftString;
       P.Direction := pdInput;
       P.Name := 'NAME';

       P := Parameters.AddParameter;
       P.DataType := ftInteger;
       P.Direction := pdOutput;
       P.Name := 'ID';

       CommandText :=
          'INSERT INTO GOODS(GOOD_NAME) VALUES (:NAME)'#13#10+
          'SELECT :ID = SCOPE_IDENTITY()';

       Parameters.ParamByName('NAME').Value := 'Дядя Вася 7';

       ShowMessage(DirectionNames[ord(Parameters.ParamByName('ID').Direction)]);

       Parameters.ParamByName('ID').Direction := pdOutput; //принудительная установка еще раз

       Execute;

       ShowMessage(DirectionNames[ord(Parameters.ParamByName('ID').Direction)]);

       if Parameters.FindParam('ID') = nil then
         ShowMessage('Параметр не найден')
       else if Parameters.ParamByName('ID').Value = Null then
         ShowMessage('Параметр вернул значение NULL. sniknik © зря упорствует в своей неправоте')
       else
         ShowMessage(Format('Значение выходного параметра ID = %s'#13+
                            'sniknik © был бы прав, если бы сказал, что коллекция Parameters ADO кривая'#13+
                            'и работает не так, как разработчик от нее ожидает,'#13+
                            'то есть параметры меняют свое Direction после парсинга текста запроса'#13+
                            'и их Direction нужно ЕЩЕ РАЗ пересустанавливать ОБЯЗАТЕЛЬНО ПОСЛЕ присвоения'#13+
                            'текста свойству CommandText, а не так как это обычно принято у нормальных людей.',
                            [IntToStr(Parameters.ParamByName('ID').Value)]));
     finally
       Free;
     end;
    end;



    То есть свойства Direction параметров в коллекции Parameters, редактируемые дизайн-тайм в компонентах ADO Delphi являются никому не нужной бутафорией, призванной лишь сбить с толку разработчика.
  • sniknik © (09.09.08 14:59) [51]
    блин, еще одно, сравнение с нил > Value = Null не совсем верно (а в базах/запросах так совсем неверно), для проверок есть свойство isNull.

    кстати а почему > Value := 'Дядя Вася'; ты вносишь правильно, после? а не при создании. видать чегото подозревал? ;)
  • kaif © (09.09.08 15:01) [52]
    2 Ega23 ©   (09.09.08 14:55) [49]

    Я готов принести свои извинения, если господин извинится передо мной за то, что многократно обвинил меня во вранье.
    Я нигде ни разу не врал.
    Мне это совершенно ни к чему.
  • sniknik © (09.09.08 15:02) [53]
    > А вот решение проблемы.
    поверь ЭТО не решение.

    > то вопрос был бы исчерпан еще вчера.
    если бы ты вчера привел этот код "для тупых"...

    > //принудительная установка еще раз
    это не еще раз, это единственная которая нужна...
  • kaif © (09.09.08 15:05) [54]
    sniknik ©   (09.09.08 14:59) [51]
    блин, еще одно, сравнение с нил > Value = Null не совсем верно (а в базах/запросах так совсем неверно), для проверок есть свойство isNull.

    кстати а почему > Value := 'Дядя Вася'; ты вносишь правильно, после? а не при создании. видать чегото подозревал? ;)


    Подозрительность твоя не знает границ. Я вношу параметр NAME после просто потому что я всегда сначала присваиваю текст, а потом задаю значения параметров. У меня такая привычка. А вот привычки думать, что свойства, определенные в дизайнере меняются на ходу без того чтобы об этом было предупреждение в документации у меня нет.
    Я же не предполагаю, например, что после выполнения метода Execute мне нужно еще раз, например, CommandText вписывать.

    А откуда я знаю?

    Может он очистился сдуру. Команда ведь "ушла на сервер".
    От этих ADO я уже чего угодно могу ожидать...
  • kaif © (09.09.08 15:06) [55]
    sniknik ©   (09.09.08 15:02) [53]
    > А вот решение проблемы.
    поверь ЭТО не решение.


    Что ты имеешь в виду?
  • sniknik © (09.09.08 15:13) [56]
    > Что ты имеешь в виду?
    procedure TSimpleReferenceForm.Button1Click(Sender: TObject);
    begin
    with TADOCommand.Create(nil) do
    try
      Connection := MainData.Connection;
      CommandText :=
         'INSERT INTO GOODS(GOOD_NAME) VALUES (:NAME)'#13#10+
         'SELECT :ID = SCOPE_IDENTITY()';

      Parameters.ParamByName('NAME').Value := 'Дядя Вася 7';
      Parameters.ParamByName('ID').Direction := pdOutput;
      Execute;

      ShowMessage(Parameters.ParamByName('ID').Value);
    finally
      Free;
    end;
    end;


    вот решение, в выделенной строке, все остальное только запутывание себя же (меня уже не удастся...).
  • kaif © (09.09.08 15:13) [57]
    sniknik ©   (09.09.08 14:59) [51]
    блин, еще одно, сравнение с нил > Value = Null не совсем верно (а в базах/запросах так совсем неверно), для проверок есть свойство isNull.


    Ты невнимательно смотришь. Сравнение с nil у меня при поиске параметра методом FindParam. Имеется в виду пустой указатель. А сравнение с Null у меня в другом месте. Там я просто сравниваю две переменные типа Variant. И такое сравнение корректно. Хотя IsNull красивее, разумеется.

    А в базах данных NULL никакого отношения к этому вообще не имеет. Просто в Delphi тип данных NULL (неопределенное значение в базе данных) в выходной параметр помещается как типа Variant со значением Null. Больше ничего.
  • MsGuns © (09.09.08 15:15) [58]
    >kaif ©   (09.09.08 14:31) [44]

    В глубоко научный спор не вмешиваюсь, а только спрошу - зачем, Ашот, ты упорно пытаешься закатить солнце вручную, т.е. пишешь код по созданию и инициализации параметров, ведь это требуется только в исключительных случаях и то, если ParamCheck := false, что, ИМХО, бывает нужным лишь в исключительных случаях ?
    И еще вопрос - зачем эти спецсимволы в строке запроса ?

    По поводу TADOQuery позволю себе не согласиться с авторитетами - вполне удобный компонент, в частности по простоте анализа RowsAffected. Что же касается глюка SQL.Add (есть такая кака), то вполне лечится SQL.Text := ..

    У меня также не возникает проблем с использованием ADO и даже более того, - считаю эту оболочку самой удобной из всех, которыми пользовался при работе с БД

    Что же касается транзакций в MSSQL скажу только, что внятного описания самого механизма так и не нашел, хотя искал во вмногих толстых книжках. Все, что вычитал - это приоритет внешних транзакций перед внутренними. И рекомендации использовать явное управление транзакциями в триггерах только в крайних случаях и будучи достаточно уверенным в их необходимости и корректности. По сравнению с ИБ транзакции в МССКЛ "несколько" запутаннее.

    И еще, чисто из собственного опыта - старт транзакции и ее завершение на клиенте не рекомендуется вкладывать в текст запроса - лучше это делать, используя TADOConnection.BeginTrans/CommitTrans|RollbackTrans - во-первых "прозрачнее" с т.з. кода, во-вторых в МсСкл нет понятия "транзакция" как самостоятельная величина (как в ИБ) и все они интерпретируются сервером применительно к соединению в целом - поэтому чтобы не запутаться в "ручных" транзакциях (в смысле где внешняя, а где внутренняя), лучше разруливать их в контексте не запроса, а всего соединения в целом.
    Что касается бизнес-логики, то там несколько другой принцип, но "база" ессно та же.
  • kaif © (09.09.08 15:17) [59]
    sniknik ©   (09.09.08 15:13) [56]

    По-твоему я не вижу, в чем разница между тем текстом и этим текстом? Если уж я написал их оба, я наверно знал, что делаю.

    Хотя ты сейчас опять скажешь, что я вру.
    Похоже ты всерьез думаешь, что все вокруг одни сплошные идиоты, кроме тебя.
 
Конференция "Базы" » ADO и MS SQL - посоветуйте хорошую ссылку [MSSQL]
Есть новые Нет новых   [134435   +35][b:0][p:0.003]