Как разбить SQL запрос на составные части для дальнейшего использования в SQLiteDatabase?
Всем привет.
С JAVAй я знаком недавно и стандартные средства работы с SQL мне не понравились.
Я привык запрос писать «одной строкой». Но в классе SQLiteDatabase нельзя отправить сырой запрос, а нужно отдельно заполнять данными каждый метод (.update(), .query(), .insert() . ).
Пример:
INSERT INTO `tb_users` (`id`,`nick`) VALUES (234,'user_nuck');
Есть ли стандартные методы для разбора запроса, чтобы его в последующем использовать в .insert(String table, String nullColumnHack, ContentValues values) и т.п.? А то в ручную парсить побаиваюсь, мало ли, ошибусь где-нибудь ))
- Вопрос задан более трёх лет назад
- 546 просмотров
STRING_SPLIT (Transact-SQL)
STRING_SPLIT — это табличное значение функция, которая разбивает строку на строки подстроек на основе указанного символа разделителя.
Уровень совместимости 130
STRING_SPLIT требует, чтобы уровень совместимости был не менее 130. Если уровень меньше 130, ядро СУБД не удается найти функцию STRING_SPLIT .
Сведения об изменении уровня совместимости базы данных см. в статье Просмотр или изменение уровня совместимости базы данных.
Конфигурация совместимости не нужна STRING_SPLIT в Azure Synapse Analytics.
Синтаксис
STRING_SPLIT ( string , separator [ , enable_ordinal ] )
Аргументы
string
Выражение любого типа символа (например, nvarchar, varchar, nchar или char).
separator
enable_ordinal
Область применения: База данных SQL Azure, Управляемый экземпляр SQL Azure, Azure Synapse Analytics (только бессерверный пул SQL) и SQL Server 2022 (16.x) и более поздних версий
Выражениеint или bit, которое служит флагом для включения или отключения выходного столбца ordinal . Значение 1 включает ordinal столбец. Если enable_ordinal опущен NULL или имеет значение 0 , ordinal столбец отключен.
Типы возвращаемых данных
Если выходной ordinal столбец не включен, возвращает таблицу с одним столбцом, STRING_SPLIT строки которой являются подстроками. Имя столбца — value . Возвращает значение типа nvarchar, если любой из входных аргументов имеет тип nvarchar или nchar. В противном случае возвращается значение типа varchar. Длина типа возвращаемого значения равна длине аргумента string.
Если аргумент enable_ordinal передается значение 1 , возвращается второй столбец ordinal , состоящий из 1-х значений индексов позиции каждой подстроки в входной строке. Тип возвращаемого значения — bigint.
Замечания
STRING_SPLIT вводит строку с разделителями и вводит один символ для использования в качестве разделителя или разделителя. При необходимости функция поддерживает третий аргумент со значением 0 или отключает или 1 включает соответственно выходной ordinal столбец.
STRING_SPLIT выводит таблицу с одним столбцом или двойным столбцом в зависимости от аргумента enable_ordinal .
- Если enable_ordinal , NULL опущен или имеет значение 0 , возвращает таблицу с одним столбцом, STRING_SPLIT строки которой содержат подстроки. Имя выходного столбца — value .
- Если enable_ordinal имеет значение 1 , функция возвращает таблицу с двумя столбцами, включая ordinal столбец, состоящий из 1 значений индексов подстроок в исходной входной строке.
Аргумент enable_ordinal должен быть константным значением, а не столбцом или переменной. Он также должен быть битом или типом данных int со значением 0 или 1 . В противном случае функция вызывает ошибку.
Выходные строки могут быть расположены в любом порядке. Порядок не гарантирует соответствие порядка подстроек во входной строке. Можно переопределить окончательный ORDER BY порядок сортировки с помощью предложения инструкции SELECT , например ORDER BY value или ORDER BY ordinal .
0x0000 (char(0)) — это неопределенный символ в параметрах сортировки Windows и не может быть включен в STRING_SPLIT него.
Пустые строки нулевой длины присутствуют в том случае, если входная строка содержит два или несколько последовательных вхождений знака разделителя. Пустые подстроки обрабатываются так же, как и обычные подстроки. Вы можете отфильтровать все строки, содержащие пустую подстроку, с помощью WHERE предложения, например WHERE value <> » . Если входная строка имеет значение NULL , STRING_SPLIT функция с табличным значением возвращает пустую таблицу.
Например, в следующей SELECT инструкции в качестве разделителя используется символ пробела:
SELECT value FROM STRING_SPLIT('Lorem ipsum dolor sit amet.', ' ');
При выполнении практики предыдущий SELECT возвращает следующую таблицу результатов:
| значение |
|---|
| Lorem |
| ipsum |
| dolor |
| sit |
| amet. |
Следующий пример включает ordinal столбец, передав 1 необязательный третий аргумент:
SELECT * FROM STRING_SPLIT('Lorem ipsum dolor sit amet.', ' ', 1);
Затем эта инструкция возвращает следующую результирующую таблицу:
| значение | ordinal |
|---|---|
| Lorem | 1 |
| ipsum | 2 |
| dolor | 3 |
| sit | 4 |
| amet. | 5 |
Примеры
А. Разделение строки значений с разделителями-запятыми
Следующая инструкция анализирует разделенный запятыми список значений и возвращает все непустые токены:
DECLARE @tags NVARCHAR(400) = 'clothing,road,,touring,bike' SELECT value FROM STRING_SPLIT(@tags, ',') WHERE RTRIM(value) <> '';
STRING_SPLIT возвращает пустую строку, если нет ничего между разделителем. Условие RTRIM(value) <> » удаляет пустые маркеры.
B. Разделение строки значений с разделителями-запятыми в столбце
Таблица Product содержит столбец с разделенным запятыми списком тегов, как показано в следующем примере:
| ИД продукта | Имя. | Теги |
|---|---|---|
| 1 | Full-Finger Gloves | clothing,road,touring,bike |
| 2 | LL Headset | bike |
| 3 | HL Mountain Frame | bike,mountain |
Следующий запрос преобразовывает каждый список тегов и соединяет его с исходной строкой:
SELECT ProductId, Name, value FROM Product CROSS APPLY STRING_SPLIT(Tags, ',');
| ИД продукта | Имя. | Значение |
|---|---|---|
| 1 | Full-Finger Gloves | clothing |
| 1 | Full-Finger Gloves | road |
| 1 | Full-Finger Gloves | touring |
| 1 | Full-Finger Gloves | bike |
| 2 | LL Headset | bike |
| 3 | HL Mountain Frame | bike |
| 3 | HL Mountain Frame | mountain |
Порядок выходных данных может отличаться, так как порядок не гарантирует соответствие порядка подстроек во входной строке.
C. Объединение по значениям
Пользователю необходимо создать отчет, в котором приводится число продуктов по каждому тегу, причем теги упорядочены по числу продуктов, и отфильтрованы теги с более чем двумя продуктами.
SELECT value as tag, COUNT(*) AS [number_of_articles] FROM Product CROSS APPLY STRING_SPLIT(Tags, ',') GROUP BY value HAVING COUNT(*) > 2 ORDER BY COUNT(*) DESC;
D. Поиск по значению тега
Разработчикам необходимо создать запросы для поиска статей по ключевым словам. Они могут использовать представленные ниже запросы.
Поиск продуктов с одним тегом (clothing):
SELECT ProductId, Name, Tags FROM Product WHERE 'clothing' IN (SELECT value FROM STRING_SPLIT(Tags, ','));
Поиск продуктов с двумя тегами (clothing и road):
SELECT ProductId, Name, Tags FROM Product WHERE EXISTS (SELECT * FROM STRING_SPLIT(Tags, ',') WHERE value IN ('clothing', 'road'));
Д. Поиск строк по списку значений
Разработчикам необходимо создать запрос, который находит статьи по списку идентификаторов. Они могут использовать следующий запрос:
SELECT ProductId, Name, Tags FROM Product JOIN STRING_SPLIT('1,2,3',',') ON value = ProductId;
Предыдущее STRING_SPLIT использование является заменой общего антипаттерна. Такой антипаттерн может включать создание динамической строки SQL на уровне приложения или в Transact-SQL. Или можно добиться антипаттерна с помощью LIKE оператора. См. следующую инструкцию: SELECT
SELECT ProductId, Name, Tags FROM Product WHERE ',1,2,3,' LIKE '%,' + CAST(ProductId AS VARCHAR(20)) + ',%';
F. Поиск строк по порядковым значениям
Следующая инструкция позволяет найти все строки с четным значением индекса:
SELECT * FROM STRING_SPLIT('Austin,Texas,Seattle,Washington,Denver,Colorado', ',', 1) WHERE ordinal % 2 = 0;
Приведенная выше инструкция возвращает следующую таблицу:
| значение | ordinal |
|---|---|
| Техас | 2 |
| Вашингтон | 4 |
| Колорадо | 6 |
G. Упорядочение строк по порядковым номерам
Следующая инструкция возвращает разделенные значения подстрок входной строки и их порядковые значения, упорядоченные столбцу ordinal :
SELECT * FROM STRING_SPLIT('E-D-C-B-A', '-', 1) ORDER BY ordinal DESC;
Приведенная выше инструкция возвращает следующую таблицу:
| значение | ordinal |
|---|---|
| А | 5 |
| Б | 4 |
| О | 3 |
| D | 2 |
| E | 1 |
Связанный контент
- LEFT (Transact-SQL)
- LTRIM (Transact-SQL)
- RIGHT (Transact-SQL)
- RTRIM (Transact-SQL)
- SUBSTRING (Transact-SQL)
- TRIM (Transact-SQL)
- Строковые функции (Transact-SQL)
Обратная связь
Были ли сведения на этой странице полезными?
Обратная связь
Отправить и просмотреть отзыв по
Разбить выборку на сегменты определенной длины
Допустим, есть выборка из 99 записей и надо ее разбить на сегменты определенной длины, допустим 25. В выборке есть ключ. Пример стартовых данных: ID 1 2 3 4 5 После разбиение по 2 будет так: ID PAGE 1 1 2 1 3 2 4 2 5 3 Это легко делается через курсор. Однако, можно ли это сделать без курсора в MS SQL 2008 r2?
Отслеживать
задан 22 апр 2019 в 19:10
24.8k 12 12 золотых знаков 64 64 серебряных знака 163 163 бронзовых знака
ntile(50) over (order by id) ?
22 апр 2019 в 19:16
@teran, хм. Надо попробовать.
22 апр 2019 в 19:17
или какое нить dense_rank() over (order by rn/2) , где rn это номер строки?
22 апр 2019 в 19:19
@teran а что такое rn? Это результат другой оконной функции?
22 апр 2019 в 19:24
@iluxa1810 row_number
– user177221
22 апр 2019 в 19:26
1 ответ 1
Сортировка: Сброс на вариант по умолчанию
Дабы подытожить комментарии, возьмем тестовый пример данных из 100 последовательных номеров (предполагаем что они не такие уж и последовательные)
WITH dataset AS ( select 1 as id union all select id+1 from dataset where id < 100 ) select * from dataset;
Далее из числа ранжирующих функций можем использовать ntile(N) , который делит выборку на N групп. То есть чтобы 100 строк разбить по 2, надо разделить на 50 групп. Для общего случая можно определить это число подзапросом:
SELECTid, ntile( (select count(id)/2 from dataset) ) over (order by id) FROM dataset;
id ----------- -------------------- 1 1 2 1 3 2 4 2 5 3 6 3 7 4
Либо второй вариант - использовать функцию dense_rank() , а для ранжирования взять номера строк, поделив их нацело на желаемое число элементов в группе:
. , nums AS ( SELECT id , (row_number() OVER (ORDER BY id) -1) AS rn FROM dataset ) SELECT id, dense_rank() OVER ( ORDER BY rn/2) FROM nums
Sql как разбить запрос на части
1. Помните, что название темы должно хоть как-то отражать ее содержимое (не создавайте темы с заголовком ПОМОГИТЕ, HELP и т.д.). Злоупотребление заглавными буквами в заголовках тем ЗАПРЕЩЕНО.
2. При создании темы постарайтесь, как можно более точно описать проблему, а не ограничиваться общими понятиями и определениями.
3. Приводимые фрагменты исходного кода старайтесь выделять тегами code. /code
4. Помните, чем подробнее Вы опишете свою проблему, тем быстрее получите вразумительный совет
5. Запрещено поднимать неактуальные темы (ПРИМЕР: запрещено отвечать на вопрос из серии "срочно надо", заданный в 2003 году)
6. И не забывайте о кнопочках TRANSLIT и РУССКАЯ КЛАВИАТУРА, если не можете писать в русской раскладке
Модераторы: Akina, shadeofgray
'> SQL Script разбить на отдельные SQL запросы.
- Подписаться на тему
- Сообщить другу
- Скачать/распечатать тему
Сообщ. #1 , 05.06.11, 08:38

Рейтинг (т): 53
Есть текстовый файл, суть его содержимого - SQL запросы к БД, различного типа (Select, Create Table, Insert, Create Procedure, Alter, . )
Вопрос: как можно из этого файла выудить каждый из запросов по отдельности.
Разбивать их по разделителю ; неполучиться, т к в Create Procedure и во многих других символ ; не является концом запроса. Тогда в таких случаях можео пробовать искать ключевое слово End с ; (но опять же нужно как то найти последний End, для такого запроса, поскольку внутри него может быть много промежуточных end`ов, закрывающих соответствующие условные, циклические и прочие операции)
Так опять же разделитель ; может встретиться в тексте запроса как символ критерия запроса.
В общем у меня четко сформулирвоанного алгоритма выделения запросов пока нет. Какие мысли есть у вас?
Сообщ. #2 , 05.06.11, 08:45
Рейтинг (т): 541
Цитата SPrograMMer @ 05.06.11, 08:38
Какие мысли есть у вас?
Изучите синтаксис полностью. затем выполняйте парсинг, начиная с "наиболее длинных" структур (которые не могут быть частью другой структуры).
Сообщ. #3 , 05.06.11, 18:37
Рейтинг (т): 135
Разбивать их по разделителю ; неполучиться, т к в Create Procedure и во многих других символ ; не является концом запроса.