Как я использую список разделенных запятой значений значений как фильтр в T-SQL?

Рассмотрите возможность использования Spring Security Crypto Module

Модуль Spring Security Crypto обеспечивает поддержку симметричного шифрования, генерации ключа и кодирования пароля. Код распространяется как часть основного модуля, но не зависит ни от какого другого кода Spring Security (или Spring).

Это обеспечивает простую абстракцию для шифрования и, кажется, соответствует тому, что требуется здесь,

«Стандартный» метод шифрования - это 256-битный AES с использованием PKK # 5 PBKDF2 (на основе пароля). Функция получения ключа № 2). Этот метод требует Java 6. Пароль, используемый для генерации SecretKey, должен храниться в безопасном месте и не должен передаваться другим пользователям. Соль используется для предотвращения словарных атак на ключ в случае взлома ваших зашифрованных данных. 16-байтовый вектор случайной инициализации также применяется, поэтому каждое зашифрованное сообщение является уникальным.

Взгляд на внутренности показывает структуру, аналогичную ответу Эриксона .

Как отмечалось в этом вопросе, для этого также требуется Политика неограниченной юрисдикции Java Cryptography Extension (JCE) (иначе вы столкнетесь с InvalidKeyException: Illegal Key Size ). Его можно загрузить для Java 6 , Java 7 и Java 8 .

Пример использования

import org.springframework.security.crypto.encrypt.Encryptors;
import org.springframework.security.crypto.encrypt.TextEncryptor;
import org.springframework.security.crypto.keygen.KeyGenerators;

public class CryptoExample {
    public static void main(String[] args) {
        final String password = "I AM SHERLOCKED";  
        final String salt = KeyGenerators.string().generateKey();

        TextEncryptor encryptor = Encryptors.text(password, salt);      
        System.out.println("Salt: \"" + salt + "\"");

        String textToEncrypt = "*royal secrets*";
        System.out.println("Original text: \"" + textToEncrypt + "\"");

        String encryptedText = encryptor.encrypt(textToEncrypt);
        System.out.println("Encrypted text: \"" + encryptedText + "\"");

        // Could reuse encryptor but wanted to show reconstructing TextEncryptor
        TextEncryptor decryptor = Encryptors.text(password, salt);
        String decryptedText = decryptor.decrypt(encryptedText);
        System.out.println("Decrypted text: \"" + decryptedText + "\"");

        if(textToEncrypt.equals(decryptedText)) {
            System.out.println("Success: decrypted text matches");
        } else {
            System.out.println("Failed: decrypted text does not match");
        }       
    }
}

И пример вывода,

Salt: "feacbc02a3a697b0"
Original text: "*royal secrets*"
Encrypted text: "7c73c5a83fa580b5d6f8208768adc931ef3123291ac8bc335a1277a39d256d9a" 
Decrypted text: "*royal secrets*"
Success: decrypted text matches
6
задан Quassnoi 24 June 2009 в 13:26
поделиться

8 ответов

Попробуйте использовать Case , который служит целям IIF или тернарного оператора. Пожалуйста, проверьте эту ссылку http://msdn.microsoft.com/en-us/library/ms181765.aspx

ура

3
ответ дан 8 December 2019 в 17:26
поделиться

Если @locid - это список, например, «33, 234» и т. Д., Тогда никакое решение здесь не сработает. Однако я полагаю, что они были опубликованы до вашего обновления с этой информацией.

Я предполагаю, что, поскольку вы сказали это:

@locid - это результаты, полученные user, например '33, 234 '

. Вы не можете напрямую расширить переменную так, чтобы location_in IN (33, 234) . На самом деле вы запрашиваете location_id = '33, 234 ', что приведет к ошибке преобразования CAST из-за приоритета типа данных.

Сначала вам нужно преобразовать список в форму таблицы для использования в JOIN / EXISTS конструкция. Есть несколько вариантов, и Эрланд описывает их все здесь: Массивы и списки в SQL Server 2005

3
ответ дан 8 December 2019 в 17:26
поделиться

См. Эту запись в моем блоге:

Если ваш @lid представляет собой список целых чисел, разделенных запятыми , используйте это:

WITH    cd AS
        (
        SELECT  1 AS first, CHARINDEX(',', @lid, 1) AS next
        UNION ALL
        SELECT  next + 1, CHARINDEX(',', @lid, next + 1)
        FROM    cd
        WHERE   next > 0
        ),
        lid AS
        (
        SELECT  CAST(SUBSTRING(@lid, first, CASE next WHEN 0 THEN LEN(@lid) + 1 ELSE next END - first)AS INT) AS id
        FROM    cd
        )
SELECT  d.*
FROM    (
        SELECT  DISTINCT id
        FROM    lid
        ) l
JOIN    apps a
ON      a.location_id = l.id
        AND @lid <> '0'
UNION ALL
SELECT  *
FROM    apps a
WHERE   @lid = '0'

Это намного эффективнее, чем использование конструкций OR .

2
ответ дан 8 December 2019 в 17:26
поделиться

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

Это фрагмент кода T-SQL, который разбивает список, разделенный запятыми, и вставляет элементы во временную таблицу. После того, как вы заполнили таблицу, вы можете присоединиться к ней.

-- This bit splits up a comma separated list of key columns
-- and inserts them in order into a table. 
--
if object_id ('tempdb..#KeyCols') is not null
    drop table #KeyCols

create table #KeyCols (
      ,KeyCol           nvarchar (100)
)

set @comma_pos = 0
set @len = len(@KeyCols)
while @len > 0 begin
    set @comma_pos = charindex(',', @KeyCols)
    if @comma_pos = 0 begin
        set @KeyCol = @KeyCols
        set @KeyCols = ''
    end else begin
        set @KeyCol = left (@KeyCols, @comma_pos - 1)
        set @KeyCols = substring(@KeyCols, 
                                 @comma_pos + 1, 
                                 len (@KeyCols) - @comma_pos)
    end
    insert #KeyCols (KeyCol)
    values (@KeyCol)
    set @len = len (@KeyCols)
end
1
ответ дан 8 December 2019 в 17:26
поделиться

Для этого вам не нужен тернарный оператор:

SELECT top 20 application_id, [name], location_id
FROM apps
WHERE (@lid > 0 AND location_id IN (@lid)) OR @lid <= 0
0
ответ дан 8 December 2019 в 17:26
поделиться

Следующее должно помочь вам.

DECLARE @lid SMALLINT

SET @lid = 0

SELECT top 20 application_id , [имя], location_id

FROM apps

WHERE ((@lid> 0 AND location_id = @lid)

  OR (@lid = 0 AND location_id > @lid))

Если @lid = 0, он вернет ВСЕ строки. ЕСЛИ @lid имеет определенное значение, возвращается только строка для этого значения @lid.

0
ответ дан 8 December 2019 в 17:26
поделиться

Хотя использование 1 = 1 - не лучшая практика, здесь есть трюк.

SELECT top 20 application_id, [name], location_id FROM apps
WHERE
  (@lid > 0 and @lid = location_id)
or
  (isnull(@lid, 0) <= 0 and 1=1)
0
ответ дан 8 December 2019 в 17:26
поделиться

Здесь вы задаете разные вопросы. Это ответ на ваш исходный вопрос (о тернарном операторе, но, как вы можете видеть, для этого вам не нужно ничего вроде тернарного оператора):

SELECT top 20 application_id, [name], location_id 
FROM apps
WHERE @lid = 0 OR location_id IN (@lid)

Но это было до того, как мы узнали, что @lid был varchar и могут содержать разные значения, разделенные запятыми.

Что ж, это (о csv) - еще один вопрос, который задавался здесь раньше:

Передача списка "входящего" через хранимую процедуру
Хранимая процедура T-SQL, которая принимает несколько значений идентификатора

0
ответ дан 8 December 2019 в 17:26
поделиться