Это самый простой:
select * from tbl where replace(col,'0','') = ''
Если вы не создадите вычисляемый столбец для этого выражения, вы можете выбрать индекс на основе функций (примечание: Oracle и Postgres уже поддерживают это; Sql Server с версии 2008, пока нет), чтобы сделать этот исполнитель:
create index ix_tbl on tbl(replace(col,'0',''))
[EDIT]
Я просто оставляю ответ ниже для потомков, я пытался объяснить, как заставить запрос использовать индекс из вычисляемого столбца.
Используйте это:
select * from tbl
where ISNUMERIC(col) = 1 and cast(col as int) = 0
Для ISNUMERIC потребностей в Oracle используйте это: http://www.oracle.com/technology/oramag/oracle/04-jul/o44asktom.html
[EDIT]
@ Charles, re: вычисляемый столбец в Oracle:
Для СУБД, которые поддерживают вычисляемый столбец, но не имеют сохраняемой опции, да, она будет вызывать функцию для каждой строки. Если он поддерживает постоянный столбец, он не будет вызывать функцию, у вас есть реальный столбец в таблице, который предварительно вычисляется из этой функции. Теперь, если данные могут заставить функцию вызывать исключение, есть два сценария.
Во-первых, если вы не указали постоянство, это позволит вам сохранить вычисляемый столбец (ALTER TABLE tbl ADD numeric_equivalent AS cast(col as int)
), даже если результат из данных вызовет исключение, но вы не можете безоговорочно выбрать этот столбец, это вызовет исключение:
select * from tbl
исключение не возникнет:
select * from tbl where is_col_numeric = 1
это будет:
select * from tbl where numeric_equivalent = 0 and is_col_numeric = 1
это не будет (Sql Server поддерживает короткое замыкание ):
select * from tbl where is_col_numeric = 1 and numeric_equivalent = 0
Для справки приведенный выше is_col_numeric был создан с использованием этого:
ALTER TABLE tbl ADD
is_col_numeric AS isnumeric(col)
И это индекс is_col_numeric:
create index ix_is_col_numeric on tbl(is_col_numeric)
Теперь для второго сценария вы помещаете вычисляемый столбец с параметром PERSISTED в таблицу, в которой уже есть существующие данные (например, 'ABXY', 'X1', 'ETC'), которая вызывает исключение, когда применяется функция / выражение (например, приведение) к этому ваша СУБД не позволит вам сделать вычисляемый столбец. Если в вашей таблице нет данных, это позволит вам включить опцию PERSISTED, но впоследствии, когда вы попытаетесь вставить данные (например, insert into tbl(col) values('ABXY')
), которые вызывают исключение, ваша СУБД не позволит вам сохранить ваши данные. Таким образом, в вашей таблице может быть сохранен только числовой текст, ваш вычисляемый столбец PERSISTED выродится в проверку ограничений, хотя и полную в обход.
Для справки вот пример сохраненного вычисляемого столбца:
ALTER TABLE tbl ADD
numeric_equivalent AS cast(col as int) persisted
Теперь у некоторых из нас может возникнуть желание не включать опцию PERSISTED в вычисляемый столбец. Это было бы своего рода самоубийственным усилием с точки зрения производительности, потому что вы не сможете создать индекс для них позже. Когда позже вы захотите создать индекс для неискаженного вычисляемого столбца, а в таблице уже есть данные «ABXY», база данных не позволит вам создать индекс. Создание индекса должно получить значение из столбца, и если этот столбец вызывает исключение, он не позволит вам создать индекс для него.
Если мы попытаемся немного обмануть, т. Е. Мы сразу создадим индекс для этого неисчисляемого вычисляемого столбца при создании таблицы, база данных позволит вам это сделать. Но когда мы добавим «ABXY» в таблицу позже, она не будет сохранена, база данных автоматически строит индекс (ы) после того, как мы вставим данные в таблицу. Конструктор индекса получает исключение вместо данных, поэтому он не может сделать запись индекса для данных, которые мы пытались вставить, поэтому последующая вставка данных не произойдет.
Так как мы можем достичь нирваны индекса для вычисляемого столбца? Прежде всего, мы должны убедиться, что вычисляемый столбец PERSISTED, и это обеспечит немедленное срабатывание ошибок; если мы не включим опцию PERSISTED, все, что может вызвать исключение, будет отложено до построения индекса, что приведет к неудаче позже. Ошибки легче найти, когда они случаются раньше. После того, как столбец сохранится, поместите в него индекс
Так что, если у нас есть существующие данные '00', '01', '2', это позволит нам создать постоянный вычисляемый столбец.Теперь после этого, если мы вставим 'ABXY', он не будет вставлен, база данных не сможет сохранить ничего из вычисляемого столбца, который вызвал исключение.Таким образом, мы просто бросим наш собственный приведение, которое не вызывает исключение.
Чтобы (просто перевести это в эквивалент Oracle):
create function cast_as_int(@n varchar(20)) returns int with schemabinding
begin
begin try
return cast(@n as int);
end try
begin catch
return null;
end catch
end;
Обратите внимание, что перехват исключения в UDF будетеще не работает в Sql Server, но Microsoft планирует поддержать этот
Теперь это наш постоянный вычисляемый столбец без исключений:
ALTER TABLE tbl ADD
numeric_equivalent AS cast_as_int(a) persisted
Удалитесуществующий индекс, а затем воссоздать его:
create index ix_num_equiv on tbl(numeric_equivalent)
Теперь этот запрос станет постоянным гражданином индекса, исполнителем и не будет вызывать исключения даже при обратном порядке условий:
select * from tbl where numeric_equivalent = 0 and is_col_numeric = 1
Чтобы сделать его более производительным, поскольку столбец numeric_equivalent больше не вызывает исключений, мы больше не используем is_col_numeric, поэтому просто используйте это:
select * from tbl where numeric_equivalent = 0