SQL - найти все строки в ВЕРХНЕМ РЕГИСТРЕ

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

Можно ли выполнять запросы с учетом регистра? В частности, я хотел бы найти все строки в определенном столбце в верхнем регистре. Это то, что я пробовал:

select *
from MyTable
where 
column1 = upper(column1) collate SQL_Latin1_General_CP1_CS_AS

person AndroidAL    schedule 10.08.2015    source источник
comment
Я думаю, что подход в вашем примере должен работать. Вы пробовали, и если да, то не получилось?   -  person jpw    schedule 10.08.2015


Ответы (3)


У тебя получилось с первого раза.

SELECT * FROM MyTable WHERE Column1 = UPPER(Column1) COLLATE SQL_Latin1_General_CP1_CS_AS

Приведенное выше является самым простым и, по-видимому, самым быстрым. Это замедлит работу, поместив его в функцию, и теперь существует встроенная функция. Другие ответы заслуживают внимания по причинам объяснения.

Редактировать: Часть 2. Первоначальный вопросник также спросил: «Как мне выполнить поиск по всем таблицам и столбцам в базе данных?». Вот быстрый способ найти. Если вы хотите вернуть все поля, в которых все заглавные буквы, просто удалите «TOP 1» из приведенной ниже процедуры, но будьте осторожны. Если у вас больше, чем много записей, вам, вероятно, не хватит памяти.

CREATE PROCEDURE SP_SearchAllTablesForAFieldWithAllCapitals
AS
BEGIN
    CREATE TABLE #Results (ColumnName nvarchar(370), ColumnValue nvarchar(3630))

    SET NOCOUNT ON

    DECLARE @TableName nvarchar(256), @ColumnName nvarchar(128)
    SET  @TableName = ''

    WHILE @TableName IS NOT NULL
    BEGIN
        SET @ColumnName = ''
        SET @TableName = 
        (
            SELECT MIN(QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME))
            FROM    INFORMATION_SCHEMA.TABLES
            WHERE       TABLE_TYPE = 'BASE TABLE'
                AND QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME) > @TableName
                AND OBJECTPROPERTY(
                        OBJECT_ID(
                            QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME)
                             ), 'IsMSShipped'
                               ) = 0
        )

        WHILE (@TableName IS NOT NULL) AND (@ColumnName IS NOT NULL)
        BEGIN
            SET @ColumnName =
            (
                SELECT MIN(QUOTENAME(COLUMN_NAME))
                FROM    INFORMATION_SCHEMA.COLUMNS
                WHERE       TABLE_SCHEMA    = PARSENAME(@TableName, 2)
                    AND TABLE_NAME  = PARSENAME(@TableName, 1)
                    AND DATA_TYPE IN ('char', 'varchar', 'nchar', 'nvarchar')
                    AND QUOTENAME(COLUMN_NAME) > @ColumnName
            )

            IF @ColumnName IS NOT NULL
            BEGIN
                INSERT INTO #Results
                EXEC
                (
                    'SELECT TOP 1''' + @TableName + '.' + @ColumnName + ''', LEFT(' + @ColumnName + ', 3630) 
                    FROM ' + @TableName + ' (NOLOCK) ' +
                    ' WHERE ' + @ColumnName + ' = UPPER(' + @ColumnName + ') COLLATE Latin1_General_CS_AS'
                )
            END
        END 
    END

    SELECT ColumnName, ColumnValue FROM #Results
END
GO
EXEC SP_SearchAllTablesForAFieldWithAllCapitals

К вашему сведению: я использовал запрос отсюда в качестве отправной точки. Как искать во всех текстовых полях БД некоторую подстроку с помощью T-SQL

person Jason Geiger    schedule 11.08.2015
comment
Привет, Джейсон, есть ли способ запросить всю БД и заставить ее возвращать имя таблицы и имя столбца со строками в верхнем регистре? - person AndroidAL; 11.08.2015
comment
Можете ли вы объяснить больше того, что вы пытаетесь сделать? Вы ищете для поиска по всем полям? Или вы пытаетесь найти имена столбцов? - person Jason Geiger; 12.08.2015

Вы можете использовать HASHBYTES и сравнить хэш.

select *
  from MyTable
 where hashbytes('SHA1',upper(column1)) = hashbytes('SHA1',column1)

Это будет работать, даже если ваша база данных нечувствительна к регистру.

person Brian Stork    schedule 10.08.2015
comment
Да, это будет работать... но это ужасно неэффективно. Это заставляет движок выполнять эту функцию дважды для каждой отдельной строки. - person Sean Lange; 10.08.2015

Я думаю, ответ Брайана Сторка будет быстрее, чем мой. Если вы хотите, чтобы это было в функции, и не хотите, чтобы функция использовала HASHBYTES, вам нужно сделать что-то вроде этого...

CREATE FUNCTION F_IsUpper
(
    @S VARCHAR(MAX)
)
RETURNS BIT
AS
BEGIN
    DECLARE @Result AS BIT
    SET @Result = 0

    IF @S = UPPER(@S) COLLATE Latin1_General_CS_AS
    BEGIN
        SET @Result = 1
    END
    RETURN @Result
END
GO
SELECT * FROM MyTable WHERE DBO.F_IsUpper(column1)= 1
person Jason Geiger    schedule 10.08.2015
comment
Я не думаю, что это эффективный способ ведения дел. Я разместил это там в образовательных целях. То, как вы это указали в операторе Main SQL выше, вероятно, правильно. Пожалуйста, не голосуйте против, потому что это негативно влияет на людей, которые пытаются помочь репутации. Вместо этого опубликуйте свой собственный ответ, и за него проголосуют. - person Jason Geiger; 10.08.2015
comment
Я не минусовал, но не в том, чтобы поддерживать репутацию человека за бесполезные ответы. Понижение означает, что ответ бесполезен. Хотя я не обязательно думаю, что это бесполезно, я задаюсь вопросом, почему это вообще было опубликовано, если вы уже заявили, что не считаете это очень хорошим. Другой ответ сам по себе плохой с точки зрения эффективности и добавляет много сложности без всякой пользы. Лучший способ сделать это - отправить запрос, опубликованный ОП. - person Sean Lange; 10.08.2015
comment
@SeanLange Мы согласны не поддерживать репутацию бесполезными вопросами. Однако отрицание ответа с нулевой репутацией немного вредит тем, кто пытается ответить серьезно. Кроме того, ответ с 0 голосами по-прежнему может иметь образовательную ценность или помочь в объяснении вопроса в целом новым читателям. - person Jason Geiger; 12.08.2015
comment
К сожалению, это не ТАК работает. Оно основано на заслугах, а не на намерении. Этот форум не предназначен для обучения. Для более конструктивного типа форума sql server вы можете взглянуть на sqlservercentral.com. Там поддерживается менталитет обучения и поощряется. Здесь речь идет больше об ответе, а наставничество отходит на второй план. - person Sean Lange; 12.08.2015