На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! информация о разделе
user posted imageДанный раздел предназначается исключительно для обсуждения вопросов использования языка запросов SQL. Обсуждение общих вопросов, связанных с тематикой баз данных - обсуждаем в разделе "Базы данных: общие вопросы". Убедительная просьба - соблюдать "Правила форума" и не пренебрегать "Правильным оформлением своих тем". Прежде, чем создавать тему, имеет смысл заглянуть в раздел "Базы данных: FAQ", возможно там уже есть ответ.

Модераторы: Akina
  
> Непонятки с датой
    На своём компе поставил MS SQL Server и в запросах из делфей использую следующий формат дат: yyyy-mm-dd, все работает, переношу прогу на другой компьютер, где в свою очередь, тоже стоит MS SQL Server с этой же базой, при попытке сделать запрос вылетает исключение - мол не могу конвертнуть дату, если же исправить формат даты на dd.mm.yyyy, то все пашет, но дома у меня так не работает. Короче, если кто-нить что-нить понял, объясните мне пожалуйста, как сделать "универсальный" формат даты?
      Универсальный формат - "YYYYMMDD HH:MM:SS".
      Ещё можно использовать команду "SET DATEFORMAT". В качестве аргумента передаётся "mdy", "ymd". А потом задавать дату в программе в соответствующем формате. Но эта команда действительна только внутри текущего коннекта.
        Цитата Lector @ 30.12.04, 11:35
        Универсальный формат - "YYYYMMDD HH:MM:SS".

        Короче у меня на компе работает, а на другом нет! Там прокатывают даты только в формате dd.mm.yyyy, почему? Может это от языка зависит?
          самы безапасныи вариант, ползоватся параметрами.
          можно восползоватся функциеи
          ExpandedWrap disabled
            FormatDateTime('YYYYMMDD', Date)

          или в запросе восползоватся функциеи
          ExpandedWrap disabled
            select CONVERT(varchar, GETDATE(), 112)
          варианты третего параметра могут быть разными.
            Цитата Kobra @ 30.12.04, 12:55
            самы безапасныи вариант, ползоватся параметрами.
            можно восползоватся функциеи FormatDateTime('YYYYMMDD', Date)

            Таки я ей и пользуюсь. У меня работает, а на другом компе - нет!
              ползуишся параметрами или ишеш в запрос отформатированую дату?
              покажи код
                Цитата Kobra @ 30.12.04, 15:32
                ползуишся параметрами или ишеш в запрос отформатированую дату?

                Шлюв запрос отформатированную дату.
                ExpandedWrap disabled
                  StrFmt(pszSQLQuery, 'select val, DateM from INTCELL where (DateM >= ''%s'' and DateM <= ''%s'') ' +
                  'and (%s) and (CounterId = %d) ORDER BY DateM ASC',
                  [FormatDateTime('yyyy.mm.dd', dtpBegin.DateTime), FormatDateTime('yyyy.mm.dd', dtpEnd.DateTime),
                  pszCells, lbCounters.ItemIndex + 1]);
                  А DateSeparator у вас не разный ?
                    Цитата Bas @ 30.12.04, 16:04
                    А DateSeparator у вас не разный ?

                    А кто его знает? Где это посмотреть?
                      ExpandedWrap disabled
                        FormatDateTime('yyyymmdd', dtpBegin.DateTime)


                      но честно сказать с параметрами работать на много безапаснее, тем более когда дело касается дат. так что я бы сделал так:
                      ExpandedWrap disabled
                          pszSQLQuery.Close;
                          pszSQLQuery.SQL.Clear;
                          pszSQLQuery.SQL.Add('select val, DateM');
                          pszSQLQuery.SQL.Add('from INTCELL');
                          pszSQLQuery.SQL.Add('where DateM >= :D1 and DateM <= :D2');
                          pszSQLQuery.SQL.Add('and ' + pszCells + ' and CounterId = :P2' );
                          pszSQLQuery.SQL.Add('ORDER BY DateM ASC');
                          pszSQLQuery.ParamByName('D1').Value := dtpBegin.DateTime;
                          pszSQLQuery.ParamByName('D2').Value := dtpEnd.DateTime;
                          ...
                          pszSQLQuery.ParamByName('P2').Value := lbCounters.ItemIndex + 1;
                          pszSQLQuery.Open;

                      pszCells - не понял что ето такое, так что написал как написал

                      Добавлено
                      кстати ету часть
                      Цитата
                      DateM >= :d1 and DateM <= :d2
                      лудше писать так
                      Цитата
                      DateM BETWEEN :d1 and :d2
                      Сообщение отредактировано: Kobra -
                        pszSQLQuery и pszCells это у меня PChar'ы ;) Ладно смысл понял, сейчас попробую...

                        Добавлено
                        1. У меня делфи говорит, что у ADOQuery нет метода ParamByName, по-идеи нужно привести его к TQuery, но хрен его знает как это делать на делфи, я на С++ пишу в основном. :whistle:
                        2. Есть ли разница в использовании методов Open()/Close() и свойства Active?
                        3.
                        Цитата Kobra @ 30.12.04, 16:40
                        кстати ету часть Цитата
                        DateM >= :d1 and DateM <= :d2
                        лудше писать такЦитата
                        DateM BETWEEN :d1 and :d2

                        Почему? Я так раньше писал, но мне больше нравиться когда видно включены ли границы интервала или нет.
                          1.
                          ExpandedWrap disabled
                            ADOQuery.Parameters.ParamByName()

                          2. разницы нет. просто когда даю команду пишу Open/Close а когда проверяю открит или нет Active
                          3. BETWEEN быстрее. а так дело хазяиское
                            Цитата Kobra @ 30.12.04, 18:00
                            3. BETWEEN быстрее. а так дело хазяиское

                            А пачему и на скока?
                              Цитата .alex @ 30.12.04, 18:34
                              А пачему и на скока?

                              наверное потому что ета одна команда, подточенная под свою задачу, а не два.
                              честно говоря не тестировал
                              Сообщение отредактировано: Kobra -
                                Цитата .alex @ 30.12.04, 08:53
                                1. У меня делфи говорит, что у ADOQuery нет метода ParamByName, по-идеи нужно привести его к TQuery, но хрен его знает как это делать на делфи, я на С++ пишу в основном.


                                Примерно так: (это лучше чем использование строк)

                                ExpandedWrap disabled
                                    pszSQLQuery.Close;
                                    pszSQLQuery.SQL.Clear;
                                    pszSQLQuery.SQL.Add('select val, DateM');
                                    pszSQLQuery.SQL.Add('from INTCELL');
                                    pszSQLQuery.SQL.Add('where DateM >= :D1 and DateM <= :D2');
                                    pszSQLQuery.SQL.Add('and ' + pszCells + ' and CounterId = :P2' );
                                    pszSQLQuery.SQL.Add('ORDER BY DateM ASC');
                                    pszSQLQuery.Parameters.ParseSQL(pszSQLQuery.SQL.text, true);
                                    
                                    pszSQLQuery.Parameters.ParamByName('D1').Value := dtpBegin.DateTime;
                                    pszSQLQuery.Parameters.ParamByName('D2').Value := dtpEnd.DateTime;
                                    ...
                                    pszSQLQuery.Parameters.ParamByName('P2').Value := lbCounters.ItemIndex + 1;
                                    pszSQLQuery.Open;
                                  Цитата Vit @ 31.12.04, 15:25
                                  Примерно так: (это лучше чем использование строк)

                                  Я так собственно и сделал, но! Проблема, как выяснилось не решилась - на домашнем компьютере работает, а на чужом нет - вылетает исключение из-за формата даты!
                                    Цитата .alex,2.01.05, 18:08 @
                                    на домашнем компьютере работает, а на чужом нет - вылетает исключение из-за формата даты!


                                    глянуть можешь на удаленном компе Язык и региональные стандарты -> Формат даты и сравнить у себя?
                                      Цитата Lavrik,2.01.05, 14:44 @
                                      глянуть можешь на удаленном компе Язык и региональные стандарты -> Формат даты и сравнить у себя?

                                      Дело в том, что у меня есть доступ только к sql server'y, а про формат даты смогу узнать только числа 10ого :( Неужели нет какого-нибудь универсального способа?
                                        Можно установить у себя в проге нужный формат.
                                        DateSeparator='.';
                                        ShortDateFormat="dd.mm.yyyy";

                                        Добавлено
                                        Цитата .alex,2.01.05, 14:04 @
                                        Неужели нет какого-нибудь универсального способа

                                        Передавать как число.
                                          Цитата Bas,2.01.05, 15:55 @
                                          Можно установить у себя в проге нужный формат.
                                          DateSeparator='.';
                                          ShortDateFormat="dd.mm.yyyy";

                                          ОК, проверю.
                                          Цитата Bas,2.01.05, 15:55 @
                                          Передавать как число.

                                          Это как? Типа тип данных не datetime, а просто целочисленный сделать?
                                            Может использовать CONVERT , особое внимание на третий параметр. Нелпа нет так что взглянуть негде :huh:
                                              тут чтото другое.
                                              когда квери получает дату как параметр, пример из моеи проги
                                              ExpandedWrap disabled
                                                 ADOQuery1.Close;
                                                  ADOQuery1.SQL.Clear;
                                                  ADOQuery1.SQL.Add('SELECT Gacdena.PerID, VPerson.person, VPerson.gankofileba, Gacdena.DateOn, Gacdena.DateOff, Gacdena.Mizezi, ');
                                                  ADOQuery1.SQL.Add('Gacdena.BNumber, Gacdena.BSeries, Gacdena.BDateOn, Gacdena.BDateOff, Gacdena.Biuletini, Gacdena.Doctor, ');
                                                  ADOQuery1.SQL.Add('Gacdena.Clinic, DATEDIFF(DD, Gacdena.DateOn, Gacdena.DateOff) + 1 AS Interval, Metka.PerID AS PerID1');
                                                  ADOQuery1.SQL.Add('FROM Gacdena INNER JOIN VPerson ON Gacdena.PerID = VPerson.perID LEFT OUTER JOIN Metka ON Gacdena.PerID = Metka.PerID');
                                                  ADOQuery1.SQL.Add('WHERE Gacdena.DateOff IS NOT NULL AND Gacdena.DateOn <= :DTP2 AND Gacdena.DateOff >= :DTP1');
                                                  ADOQuery1.SQL.Add('ORDER BY Metka.PerID DESC, VPerson.person, Gacdena.DateOn');
                                                  ADOQuery1.Parameters.ParamByName('DTP1').Value := DTP1.Date;
                                                  ADOQuery1.Parameters.ParamByName('DTP2').Value := DTP2.Date;
                                                  ADOQuery1.Open
                                              и когда он связан с SQL Server-ом запрос передает так, я скопировал запрос из профаилера
                                              ExpandedWrap disabled
                                                sp_executesql N'SELECT Gacdena.PerID, VPerson.person, VPerson.gankofileba, Gacdena.DateOn, Gacdena.DateOff, Gacdena.Mizezi,
                                                Gacdena.BNumber, Gacdena.BSeries, Gacdena.BDateOn, Gacdena.BDateOff, Gacdena.Biuletini, Gacdena.Doctor,
                                                Gacdena.Clinic, DATEDIFF(DD, Gacdena.DateOn, Gacdena.DateOff) + 1 AS Interval, Metka.PerID AS PerID1
                                                FROM Gacdena INNER JOIN VPerson ON Gacdena.PerID = VPerson.perID LEFT OUTER JOIN Metka ON Gacdena.PerID = Metka.PerID
                                                WHERE Gacdena.DateOff IS NOT NULL AND Gacdena.DateOn <= @P1 AND Gacdena.DateOff >= @P2
                                                ORDER BY Metka.PerID DESC, VPerson.person, Gacdena.DateOn
                                                ', N'@P1 datetime,@P2 datetime', '20050103 00:00:00:000', '20050101 00:00:00:000'
                                              когда квери получает дату как параметр, если конечно получает коректно, то далше уже система гарантирует правилные переобразования.
                                              исходя из етого, если в программе нписано
                                              ExpandedWrap disabled
                                                pszSQLQuery.Parameters.ParamByName('D1').Value := dtpBegin.DateTime
                                              проблем не далжно быть, так как dtpBegin.DateTime тоже автоматически генерирует система.
                                              у меня смутные подозрения на счет того, что гдето тип данных не DateTime а чтото другое, и соответственно в том месте не правилно производится конвертация.
                                              .alex устонави на тои, чужои машине делфи, и в пошаговом режиме погляди все переобразования.
                                                Цитата Kobra,3.01.05, 10:13 @
                                                .alex устонави на тои, чужои машине делфи, и в пошаговом режиме погляди все переобразования.

                                                Незя...
                                                Цитата Kobra,3.01.05, 10:13 @
                                                проблем не далжно быть, так как dtpBegin.DateTime тоже автоматически генерирует система.
                                                у меня смутные подозрения на счет того, что гдето тип данных не DateTime а чтото другое, и соответственно в том месте не правилно производится конвертация.

                                                Может проблема, в том что я использую свойство DateTime, а не Date у TDateTimePicker'a? Просто когда я переносил базу, я сначала экспортировал её в access'вскую, а потом обратно импортировал в ms sql, может в процессе экспорта/импорта поменялся тип данных поля DateM? У меня сейчас нет возможности проверить, но ваще такое возможно?
                                                  Цитата .alex,3.01.05, 17:57 @
                                                  Может проблема, в том что я использую свойство DateTime, а не Date у TDateTimePicker'a?

                                                  если в своистве Time TDateTimePicker-а стоит "0" то резултат только дата, а если чтото другое - то дата время, так что ета без разницы. протестируи, сам увидиш.

                                                  Цитата .alex,3.01.05, 17:57 @
                                                  У меня сейчас нет возможности проверить, но ваще такое возможно?
                                                  с аксесом не знаком, но что значит не могу проверить? кто мешает на своем компе протестировать аналогичную ситуацию?

                                                  и вообше, почему
                                                  Цитата .alex,3.01.05, 17:57 @
                                                  Незя...
                                                  на том компе установить своии штуки для тестировки? извени, у меня такого ограничения не бывало и не понемаю смысл.
                                                    Цитата Kobra,4.01.05, 09:47 @
                                                    кто мешает на своем компе протестировать аналогичную ситуацию?

                                                    Проверю, просто тогда не мог.
                                                    Цитата Kobra,4.01.05, 09:47 @
                                                    и вообше, почему Цитата (.alex @ 3.01.05 17:57)
                                                    на том компе установить своии штуки для тестировки? извени, у меня такого ограничения не бывало и не понемаю смысл.

                                                    Я устанавливал свои штуки не на том компе, на котором стоит сервер, а на другом, который находиться с ним в сети, а делфи я на сервере поставить не могу!
                                                    Цитата Kobra,3.01.05, 10:13 @
                                                    и когда он связан с SQL Server-ом запрос передает так, я скопировал запрос из профаилера

                                                    Где находится этот профайлер?
                                                      профаилер можно вызвать из ентерпраиз менеджера. ето одна из сервисних програм SQL Server-а. чтото на подобии борландовского SQL Monitor-а.
                                                        Короче профайлер после моего запроса: (где pszCells - это строка вида: CELLId = 1 OR CELLId = 2 OR CELLId = 3, dtpBegin и dtpEnd - это объекты класса TDateTimePicker, а lbCounters - это объект класса TListBox)
                                                        ExpandedWrap disabled
                                                          SQL.Add('SELECT val, DateM FROM INTCELL WITH (NOLOCK)');
                                                          SQL.Add('WHERE (DateM >= :D1 AND DateM <= :D2) AND (' + pszCells + ')');
                                                          SQL.Add('AND (CounterId = :P1) ORDER BY DateM ASC');
                                                          Parameters.ParamByName('D1').Value := dtpBegin.DateTime;
                                                          Parameters.ParamByName('D2').Value := dtpEnd.DateTime;
                                                          Parameters.ParamByName('P1').Value := lbCounters.ItemIndex + 1;

                                                        показывает следующий запрос:
                                                        ExpandedWrap disabled
                                                          exec sp_executesql N'SELECT val, DateM FROM INTCELL WITH (NOLOCK)
                                                          WHERE (DateM >= @P1 AND DateM <= @P2) AND (CELLId = 1 OR CELLId = 2 OR CELLId = 3)
                                                          AND (CounterId = @P3) ORDER BY DateM ASC
                                                          ', N'@P1 datetime,@P2 datetime,@P3 int', 'Dec 17 2004 10:27PM', 'Dec 24 2004 10:27PM', 1

                                                        Что-то я не понимаю почему он так извращает дату.
                                                        И ещё, почему-то перестало работать условие:
                                                        ExpandedWrap disabled
                                                          (DateM >= :D1 AND DateM <= :D2)

                                                        Все данные у меня записаны на 18 число декабря 2004г, раньше выборка работала правильно, а теперь только если я ставлю начало интервала, т.е. dtpBegin, на 17 число. :wacko:

                                                        Добавлено
                                                        И исчё! Зачем нужно:
                                                        ExpandedWrap disabled
                                                          pszSQLQuery.Parameters.ParseSQL(XXX, true);
                                                          на месте
                                                          ExpandedWrap disabled
                                                            dtpBegin.DateTime
                                                          напиши
                                                          ExpandedWrap disabled
                                                            dtpBegin.Date
                                                          и
                                                          Цитата Kobra,4.01.05, 09:47 @
                                                          если в своистве Time TDateTimePicker-а стоит "0" то резултат только дата
                                                          а ты передаеш и дату и время, соответственно
                                                          'Dec 18 2004 10:27PM' в лубом случае болше 'Dec 18 2004' и выборки нет.

                                                          'Dec 17 2004 10:27PM' в лубом случае менше 'Dec 18 2004' и выборки нормалная.

                                                          ExpandedWrap disabled
                                                            pszSQLQuery.Parameters.ParseSQL(XXX, true);
                                                          ето харошыи тон, лично я почти никогда не пишу так как ета орерация всеравно выполняется.


                                                          Цитата .alex,5.01.05, 17:01 @
                                                          Что-то я не понимаю почему он так извращает дату.
                                                          он приводит дату в тот вид, какои нравится на SQL Server-у.
                                                          как время убереш, наверняка заработает. вроде запрос правилно передается.
                                                            Цитата Kobra,5.01.05, 18:06 @
                                                            а ты передаеш и дату и время, соответственно
                                                            'Dec 18 2004 10:27PM' в лубом случае болше 'Dec 18 2004' и выборки нет.
                                                            'Dec 17 2004 10:27PM' в лубом случае менше 'Dec 18 2004' и выборки нормалная.

                                                            Понял.
                                                            Цитата Kobra,5.01.05, 18:06 @
                                                            если в своистве Time TDateTimePicker-а стоит "0" то резултат только дата

                                                            Изменил DateTime на Date и поставил в свойстве Time у обоих TDateTimePicker - 0:00:00. Все равно передаётся вместе с датой и время:
                                                            ExpandedWrap disabled
                                                              exec sp_executesql N'SELECT val, DateM FROM INTCELL WITH (NOLOCK)
                                                              WHERE (DateM >= @P1 AND DateM <= @P2) AND (CELLId = 1)
                                                              AND (CounterId = @P3) ORDER BY DateM ASC
                                                              ', N'@P1 datetime,@P2 datetime,@P3 int', 'Dec 18 2004 12:00AM', 'Dec 24 2004 12:00AM', 1

                                                            Цитата Kobra,5.01.05, 18:06 @
                                                            ето харошыи тон, лично я почти никогда не пишу так как ета орерация всеравно выполняется.

                                                            Я тоже сначала так подумал, но после того как посмотрел в профайлер, решил спросить, ибо когда я ставлю эту строчку:
                                                            ExpandedWrap disabled
                                                              SQL.Add('SELECT val, DateM FROM INTCELL WITH (NOLOCK)');
                                                              SQL.Add('WHERE (DateM >= :D1 AND DateM <= :D2) AND (' + pszCells + ')');
                                                              SQL.Add('AND (CounterId = :P1) ORDER BY DateM ASC');
                                                              Parameters.ParseSQL(SQL.Text, TRUE);
                                                              Parameters.ParamByName('D1').Value := dtpBegin.Date;
                                                              Parameters.ParamByName('D2').Value := dtpEnd.Date;
                                                              Parameters.ParamByName('P1').Value := Integer(lbCounters.Items.Objects[lbCounters.ItemIndex]);

                                                            дата приводиться к float :wacko:
                                                            ExpandedWrap disabled
                                                              exec sp_executesql N'SELECT val, DateM FROM INTCELL WITH (NOLOCK)
                                                              WHERE (DateM >= @P1 AND DateM <= @P2) AND (CELLId = 1)
                                                              AND (CounterId = @P3) ORDER BY DateM ASC
                                                              ', N'@P1 float,@P2 float,@P3 int', 3.833900000000000e+004, 3.834500000000000e+004, 1

                                                            Это нормально? :wall:
                                                            Сообщение отредактировано: .alex -
                                                              'Dec 18 2004 12:00AM' ето настроики такие и потому, если перефразировать получится "18,12,2004 00:00:00" так что ето не страшно.

                                                              Цитата .alex,5.01.05, 18:19 @
                                                              дата приводиться к float
                                                              веть дата-время хранится как число, так что система сама определяет в каком виде для него будет удобнее получить данные. ето нормално.

                                                              протести такои вариант
                                                              ExpandedWrap disabled
                                                                Parameters.ParamByName('D1').Value := StrToDate(datetostr(dtpBegin.Date));
                                                              не зависимо от устоновок DateTimePicker-а отсекает время.
                                                              Сообщение отредактировано: Kobra -
                                                                Короче при помощи параметров проблему решить не удалось, решил так:
                                                                ExpandedWrap disabled
                                                                  SET DATEFORMAT ymd

                                                                А потом в запрос вставлял дату отформатированную под формат 'yyyy-mm-dd', и все...
                                                                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                                                0 пользователей:


                                                                Рейтинг@Mail.ru
                                                                [ Script execution time: 0,0942 ]   [ 16 queries used ]   [ Generated: 19.04.24, 13:35 GMT ]