Как проверить числовой формат в SQL Server 2008 - PullRequest
1 голос
/ 28 февраля 2020

Я конвертирую некоторые существующие Oracle запросы в MS SQL Server (2008) и не могу понять, как повторить следующую проверку регулярных выражений:

SELECT SomeField
FROM SomeTable
WHERE NOT REGEXP_LIKE(TO_CHAR(SomeField), '^[0-9]{2}[.][0-9]{7}$');

, которая находит все результаты, где формат числа начинается с 2 положительных цифр, после которых следует десятичная точка и 7 десятичных знаков данных: 12.3456789

Я пытался использовать STR, CAST, CONVERT, но кажется, что все они почему-то урезают десятичный знак до 4 десятичных. Усечение помешало мне получить надежные результаты, используя LEN и CHARINDEX. Добавление параметров размера в STR вручную становится немного ближе, но я все еще не знаю, как сравнить исходное числовое представление с преобразованным значением.

SELECT SomeField
     , STR(SomeField, 10, 7)
     , CAST(SomeField AS VARCHAR)
     , LEN(SomeField )
     , CHARINDEX(STR(SomeField ), '.') 
FROM SomeTable
+------------------+------------+---------+-----+-----------+
|       Orig       |    STR     |  Cast   | LEN | CHARINDEX |
+------------------+------------+---------+-----+-----------+
| 31.44650944      | 31.4465094 | 31.4465 |   7 |         0 |
| 35.85609         | 35.8560900 | 35.8561 |   7 |         0 |
| 54.589623        | 54.5896230 | 54.5896 |   7 |         0 |
| 31.92653899      | 31.9265390 | 31.9265 |   7 |         0 |
| 31.4523333333333 | 31.4523333 | 31.4523 |   7 |         0 |
| 31.40208955      | 31.4020895 | 31.4021 |   7 |         0 |
| 51.3047869443893 | 51.3047869 | 51.3048 |   7 |         0 |
| 51               | 51.0000000 | 51      |   2 |         0 |
| 32.220633        | 32.2206330 | 32.2206 |   7 |         0 |
| 35.769247        | 35.7692470 | 35.7692 |   7 |         0 |
| 35.071022        | 35.0710220 | 35.071  |   6 |         0 |
+------------------+------------+---------+-----+-----------+

Ответы [ 2 ]

2 голосов
/ 28 февраля 2020

То, что вы хотите сделать, не имеет смысла в SQL Server.

Oracle поддерживает number тип данных , который имеет переменную точность:

, если точность не указана, столбец хранит значения, как указано.

Нет соответствующего типа данных в SQL Server. У вас есть переменное число (число с плавающей запятой / действительное число) или фиксированное число (десятичное число / число c). Однако оба они применимы ко ВСЕМ значениям в столбце, а не к отдельным значениям в строке.

Самое близкое, что вы можете сделать, это:

where somefield >= 0 and somefield < 100

Или, если вы хотите настаивать на том, что есть десятичный компонент:

where somefield >= 0 and somefield < 100 and floor(somefield) <> somefield

Однако у вас могут быть допустимые целочисленные значения, которые будут отфильтрованы.

0 голосов
/ 28 февраля 2020

Этот ответ дал мне опцию, которая работает в сочетании с проверкой десятичной позиции первой.

SELECT SomeField 
FROM SomeTable
WHERE SomeField IS NOT NULL
  AND CHARINDEX('.', SomeField ) = 3
  AND LEN(CAST(CAST(REVERSE(CONVERT(VARCHAR(50), SomeField , 128)) AS FLOAT) AS BIGINT)) = 7

Хотя я понимаю, что это ужасно почти по всем показателям, оно удовлетворяет требованиям.

Основа проверки форматирования для этого типа данных изначально ошибочна, как указывалось несколькими авторами, однако для этого очень изолированного варианта использования я хотел документировать обходной путь.

...