Оператор «<=» не работает в SQL Server 2000 - PullRequest
0 голосов
/ 11 февраля 2011

Сценарий: база данных находится на этапе обслуживания. эта база данных не разработана нашим разработчиком. это существующая база данных, разработанная компанией 'xyz' в SQL Server 2000. Это база данных в реальном времени, где я сейчас работаю. Я хотел написать хранимую процедуру, которая будет извлекать мне записи от даты1 до даты 2. поэтому запрос:

Select * from MyTableName
Where colDate>= '3-May-2010' and colDate<= '5-Oct-2010' and colName='xyzName'

тогда как, насколько я понимаю, я должен получить данные, включая верхнюю и нижнюю даты. но почему-то я получаю записи с 3 мая 2010 года (что хорошо, но) до 10 октября 2010 года

Как я заметил в дизайне таблицы, для ColDate разработчик использовал varchar для хранения даты. я знаю, что это неправильное средство от них. поэтому в своей хранимой процедуре я также использовал параметры varchar как @ FromDate1 и @ToDate для получения входных данных для SP. это дает мне результат, который я объяснил. я попытался принять тип параметра как «Datetime», но при сохранении / изменении хранимой процедуры он показывает ошибку, что «@ FromDate1 имеет неверный тип данных», то же самое для «@ToDate».

Ситуация такова, что я вообще не могу изменить дизайн стола. что мне здесь делать? Я знаю, что мы можем использовать пользовательскую таблицу в SQL Server 2008, но есть версия SQL Server 2000. которая не поддерживает то же самое. Пожалуйста, ведите меня по этому сценарию.

**Edited**

I am trying to write like this SP:

    CREATE PROCEDURE USP_Data  
    (@Location varchar(100),
    @FromDate  DATETIME,
    @ToDate DATETIME) AS

    SELECT     *
    FROM         dbo.TableName
    Where   CAST(Dt  AS DATETIME) >=@fromDate and  CAST(Dt  AS  DATETIME)<=@ToDate  and Location=@Location
    GO

but getting Error: Arithmetic overflow error converting expression to data type datetime. in sql server 2000 Что это должно быть? я где-то ошибаюсь? также

(202 row(s) affected) is changes every time in circular manner means first time sayin 
(122 row(s) affected)
run again saying 
(80 row(s) affected)
if again 
(202 row(s) affected)
if again 
(122 row(s) affected)

Не могу понять, что происходит?

Ответы [ 5 ]

1 голос
/ 11 февраля 2011

Можете ли вы CAST () или поместить представление в эту таблицу и преобразовать все даты в значения DateTime? Я не помню, если 2000 поддерживал индексные представления, но, основываясь на ваших значениях varchar (dd-mmm-yyyy), это будет кошмаром, чтобы попытаться выбрать даты (возможно, анализируя, но боль) с этими значениями.

0 голосов
/ 13 февраля 2011

Еще один способ найти неверные данные - использовать ограниченную функциональность регулярных выражений SQL Server 2000:

SELECT
  *
FROM
  MyTableName
WHERE
  colDate NOT LIKE '[1-9]-Jan-[12][0-9][0-9][0-9]'
    AND
  colDate NOT LIKE '[12][0-9]-Jan-[12][0-9][0-9][0-9]'
    AND
  colDate NOT LIKE '3[01]-Jan-[12][0-9][0-9][0-9]'
    AND
  colDate NOT LIKE '[1-9]-Feb-[12][0-9][0-9][0-9]'
    AND
  colDate NOT LIKE '1[0-9]-Feb-[12][0-9][0-9][0-9]'
    AND
  colDate NOT LIKE '2[0-8]-Feb-[12][0-9][0-9][0-9]' -- ignore Feb 29 for now
    AND

Вам придется выполнить запрос самостоятельно.

0 голосов
/ 13 февраля 2011

Похоже, вам нужно найти неверные данные.Мне тоже пришлось иметь дело с данными о дате и времени, хранящимися в столбце varchar.Может быть трудно отследить ошибочные данные.Сначала я открыл таблицу и посмотрел на нее в поисках неверно отформатированных дат, но не смог найти ни одной, поэтому решил, что их очень мало, и что было бы быстро использовать более программный подход.В конечном итоге я использовал подход «разделяй и властвуй»: я разделил данные пополам и попытался привести каждую половину к дате.Если какая-либо половина вызвала ошибку, то я далее разделил ее пополам и проверил эти половины.Это рекурсивный процесс.Я мог бы написать T-SQL для этого, но я сделал это вручную.Это заняло, возможно, полчаса.

Например, предположим, что MyTableName имеет ПЕРВИЧНЫЙ КЛЮЧ с именем MyID с последовательными значениями, начинающимися с 1 и заканчивающимися на 1000000. Затем я запускаю два запроса, чтобы проверить, какая половина (или половина)содержать недопустимые данные:

SELECT CAST(colDate AS DATETIME) WHERE MyID BETWEEN 1 AND 500000
GO
SELECT CAST(colDate AS DATETIME) WHERE MyID BETWEEN 500001 AND 1000000
GO

Если первый запрос вызвал ошибку, я бы запустил еще два запроса:

SELECT CAST(colDate AS DATETIME) WHERE MyID BETWEEN 1 AND 250000
GO
SELECT CAST(colDate AS DATETIME) WHERE MyID BETWEEN 250001 AND 500000
GO

Предположим, что в этой итерации только второй запрос вызвал ошибкуошибка.Затем я бы выполнил еще два запроса:

SELECT CAST(colDate AS DATETIME) WHERE MyID BETWEEN 250001 AND 375000
GO
SELECT CAST(colDate AS DATETIME) WHERE MyID BETWEEN 375001 AND 500000
GO

В конечном итоге - в итерациях log-base-2-of-n или менее - вы найдете первое ошибочное значение данных.Конечно, вы не знаете, сколько ошибочных значений содержится в вашей таблице, поэтому может потребоваться время, чтобы найти их все.В моем случае у меня было около 10 ошибочных значений, некоторые из которых были 'none' или 'NA' и которые я ОБНОВЛЕН был равен NULL, а некоторые из них были просто неправильно отформатированными датами, которые я ОБНОВИЛ, чтобы они были правильно отформатированы.Исправив неверные данные, я наконец смог вернуться к первоначальной задаче анализа данных.

0 голосов
/ 11 февраля 2011
SELECT
    *
FROM
    MyTableName
WHERE
    CAST(colDate AS DATETIME) >= '3-May-2010'
        and
    CAST(colDate AS DATETIME) < DATEADD(day, 1, '5-Oct-2010')
        AND
    colName = 'xyzName'
0 голосов
/ 11 февраля 2011

Вам необходимо привести «даты» в столбце varchar к фактическим datetime значениям, а затем выполнить сравнение. Кроме того, я бы рекомендовал использовать формат ГГГГММДД для ваших дат.

Select ...
From MyTableName
Where Cast(colDate As datetime) >= '20100503'
    And Cast(colDate As datetime) <= '20101005'
    And colName = 'xyzName'

Если вы передаете параметры, вы также должны принудительно установить их как datetime

Create Procedure Foo
    @FromDate datetime
    , @ToDate datetime
    ...
As
Select ...
From MyTableName
Where Cast(colDate As datetime) >= @FromDate
    And Cast(colDate As datetime) <= @ToDate
    And colName = 'xyzName'

Конечно, лучшее решение - просто изменить тип данных в таблице на datetime и исправить зависимые программы или создать пару вычисляемых столбцов, которые приведут значения varchar к datetime или просто добавить несколько статических datetime столбцов и выполните однократное обновление из столбцов varchar.

Обновление

Ошибка, которую вы получаете, заключается в том, что некоторые значения varchar не могут быть преобразованы в datetime (поэтому плохая идея иметь их как varchar). Либо эти значения должны быть исправлены, либо вы должны исключить эти значения. Чтобы найти значения, которые не являются датами, вы можете использовать функцию IsDate.

Select ...
From MyTableName
Where IsDate( colDate ) = 0

Другой способ написать запрос для исключения этих значений:

Select ...
From    (
        Select Cast(colDate As datetime) As CastedDate
            , ...
        From MyTable
        Where IsDate( colDate ) = 1
        )
Where CastedDate >= @FromDate
    And CastedDate <= @ToDate
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...