Построковая обработка sql выборки в сценарии — различия между версиями

Материал из Oktell
Перейти к: навигация, поиск
Строка 70: Строка 70:
  
  
Недостатки: Если в таблице нет числовых столбцов, то сценарий не применим.  
+
Недостатки: Если в таблице нет числовых столбцов, то сценарий не применим; если в числовом столбце повторяются значения, то будет обработано только одно из этих значений (в связи с алгоритмом).
  
  
 
=== Вариант 2 для таблицы со строковыми полями ===
 
=== Вариант 2 для таблицы со строковыми полями ===
  
 +
[[Файл:Обработка таблицы 4.PNG | center]]
  
  
[[Файл:Обработка таблицы 4.PNG | center]]
+
Начальному значению счетчика i присваиваем 0. Конечное значение счетчика ilast равняется количеству строк в таблице, которые необходимо обработать, и находится с помощью sql-запроса:
  
 +
select @ilast = count(*) from notsorted
 +
 +
Затем счетчик инкрементируется и входит в цикл. Условием окончания цикла является прохождения ilast строк, таким образом если i> ilast, то цикл заканчивает выполняться. Далее необходимо выбрать необходимую строку. Предполагая, что оперируем только со строковым полем предлагается следующий алгоритм. Строки сортируются лексикографически по убыванию, затем выбираются первые i строк. Затем выбирается самая последняя строка (полученная выборка сортируется лексикографически по возрастанию и выбирается первая запись). Таким образом происходит доступ к элементу.
 +
 +
Так как нет возможности формировать sql запрос динамически (добавив в него переменные), запрос формируется отдельно в строке sql (компонент присвоение). Вид формируемой строки:
 +
 +
'Select Top 1 name as name1
 +
From (
 +
Select Top ' +Str([i])+ ' name
 +
From notsorted
 +
Order by name desc
 +
) a
 +
Order by name asc'
 +
 +
Выполнить данный запрос можно с помощью компонента sql-запрос. При выполнении нужное значение, как видно из запроса, сохраняется в строку name1. Необходимо в сценарии заранее создать переменную с идентичным названием. Строка запроса (в параметрах определяем @sql как строку с запросом sql).
 +
 +
exec sp_executesql @sql
 +
 +
Результат:
  
 
[[Файл:Обработка таблицы 4-1.PNG | center]]
 
[[Файл:Обработка таблицы 4-1.PNG | center]]
 +
 +
Недостатки: сравнительно с первым вариантом, долгое время выполнения sql-запроса.
 +
 +
Достоинства: записи обрабатываются лексикографически; в таблице не обязательно иметь числовое поле - выборку можно сделать по строковым поля. Это полезно, если у вас нет уникальных идентификаторов в вашей таблице.

Версия 12:19, 20 сентября 2013

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

Возьмем к примеру следующую таблицу notsorted с двумя столбцами Id и name:


notsorted
id name
0 Иванов Иван
3 Петров Петр
4 Сергеев Сергей
5 Дмитриев Дмитрий
6 Алексей Алексей


Как видно в таблице id идет не по порядку. При решении данной задачи необходимо учитывать этот факт.

Классический способ решения (не применим)

Обработка таблицы 2.PNG

В самом начале счетчику i присваивается значение "-1", конечному значению счетчика присваивается количество строк в таблице с помощью запроса:

select @ilast = count(*) from notsorted

Далее реализован цикл, счетчик инкрементируется, затем сравнивается с конечным значением. Выбор значения происходит следующим sql запросом:

select @name=name from notsorted where id=@id 

С полученным значением name производятся действия.

Результат:

Обработка таблицы 2-1.PNG

Недостатки: обработка таблицы идет по значению id. Так как в таблице нет строк с id=1, 2 , то сценарий будет делать лишний цикл, выдавать ошибку на sql запросе (или выдавать одно значение несколько раз). Вариант неприменим, если в таблице нет уникального идентификатора, даже если есть некое числовое поле - если у некоторых строк оно одинаковое, то сценарий не сможет вывести эти значения.

Вариант 1 для таблицы с числовым полем

Обработка таблицы 3.PNG


Начальное значение переменной id_before присваивается "-1000", далее с помощью sql запроса получаем самый первую строку (значения id, name), у которой id > id_before. Записываем id в переменную id_after. В этом же sql запросе получаем количество строк, которые попадают под это условие. Вид запроса:

select top 1 @id=id, @name=name from notsorted where id>@id_before
set @rowcount=@@rowcount

Если количество строк, у которых условие id> id_before равно нулю (т.е. таких строк нет), то это является индикатором конца цикла. Таким образом в проверке на завершение происходит сравнение rowcount с нулем. Если строки нашлись, то присваиваем id_before текущее значение id_after. Далее совершаем необходимые действия со строкой.

Результат:


Обработка таблицы 3-1.PNG


Недостатки: Если в таблице нет числовых столбцов, то сценарий не применим; если в числовом столбце повторяются значения, то будет обработано только одно из этих значений (в связи с алгоритмом).


Вариант 2 для таблицы со строковыми полями

Обработка таблицы 4.PNG


Начальному значению счетчика i присваиваем 0. Конечное значение счетчика ilast равняется количеству строк в таблице, которые необходимо обработать, и находится с помощью sql-запроса:

select @ilast = count(*) from notsorted

Затем счетчик инкрементируется и входит в цикл. Условием окончания цикла является прохождения ilast строк, таким образом если i> ilast, то цикл заканчивает выполняться. Далее необходимо выбрать необходимую строку. Предполагая, что оперируем только со строковым полем предлагается следующий алгоритм. Строки сортируются лексикографически по убыванию, затем выбираются первые i строк. Затем выбирается самая последняя строка (полученная выборка сортируется лексикографически по возрастанию и выбирается первая запись). Таким образом происходит доступ к элементу.

Так как нет возможности формировать sql запрос динамически (добавив в него переменные), запрос формируется отдельно в строке sql (компонент присвоение). Вид формируемой строки:

'Select Top 1 name as name1
From (

Select Top ' +Str([i])+ ' name From notsorted Order by name desc

) a
Order by name asc'

Выполнить данный запрос можно с помощью компонента sql-запрос. При выполнении нужное значение, как видно из запроса, сохраняется в строку name1. Необходимо в сценарии заранее создать переменную с идентичным названием. Строка запроса (в параметрах определяем @sql как строку с запросом sql).

exec sp_executesql @sql

Результат:

Обработка таблицы 4-1.PNG

Недостатки: сравнительно с первым вариантом, долгое время выполнения sql-запроса.

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