Как улучшить классическое кодирование VBA с помощью SQL? Я делаю беспорядок с петлями. - PullRequest
1 голос
/ 29 ноября 2011

Ну ... я n00b, я это знаю.И это довольно прямолинейно.

По сути, это код, который я писал.

rstSwift.MoveFirst
Do While Not rstSwift.EOF
    If Left(rstSwift!Date, 2) & Mid(rstSwift!Date, 4, 2) & Right(rstSwift!Date, 4) = fromdate Then
        INSERTFUNCTIONHERE
    Else
    End If
    rstSwift.MoveNext
Loop

Недавно я задал вопрос о SQL, и кажется, что он имеет много решений моих проблем ... вы видите, моя текущая база данных содержит около +15000 записей - и каждый раз, когда мне нужносделать запрос обо всех записях, относящихся к одному дню, который занимает некоторое время - в конце концов, я прошу его выполнить LOOP по всей базе данных.

Теперь, до меня дошло, что я, возможно, немного глуп, чтобы делать это - ну, это был единственный способ, которым я мог это сделать - мой главный вопрос:

Могу ли я заменить это "делать пока" на SQL-запрос?Как

NEWTABLEVARIABLE = SELECT * from rstSwift WHERE rstSwift.Date = '20/11/2011';
NEWTABLEVARIABLE.MoveFirst
Do While Not NEWTABLEVARIABLE.EOF
INSERTFUNCTIONHERE
NEWTABLEVARIABLE.MoveNext
Loop

И по результатам этого запроса запустить код?Будет ли это быстрее, чем мой текущий код?Даже если это не быстрее - медленнее?Потому что кажется, что написать единственный аргумент select гораздо проще, чем иметь дело с ситуацией while-Loop ...

Ответы [ 2 ]

3 голосов
/ 30 ноября 2011

Цель должна состоять в том, чтобы полностью удалить цикл.

Скажем, INSERTFUNCTIONHERE увеличивает столбец data_col на 1: вместо:

rstSwift.MoveFirst
Do While Not rstSwift.EOF
    If Left(rstSwift!swift_date, 2) & _
          Mid(rstSwift!swift_date, 4, 2) & _
          Right(rstSwift!swift_date, 4) = fromdate Then
        rstSwift!data_col = rstSwift!data_col + 1
        rstSwift.Update
    End If
    rstSwift.MoveNext
Loop

Вместо этого переписать всю операцию в SQL, например.

CREATE PROCEDURE IncrementSwifts
(
 :fromdate DATETIME
)
AS
UPDATE Swifts
   SET data_col = data_col + 1
 WHERE swift_date = :fromdate;

Затем в VBA используйте объект Command для выполнения процедуры, используя объект Parameter для передачи значения fromdate.

2 голосов
/ 29 ноября 2011

Да, вы можете выполнить фильтрацию на стороне базы данных. Вы передадите запрос, который вы указали при открытии набора записей. Примерно так:

set rstSwift = connMyDbConnection.Execute("SELECT * from rstSwift WHERE rstSwift.Date = #20/11/2011#")
Do While Not rstSwift.EOF
   INSERTFUNCTIONHERE
   rstSwift.MoveNext
Loop

EDIT:
При использовании метода Database.OpenRecordset () используйте этот синтаксис вместо приведенного выше:

set rstSwift = mdb.OpenRecordset("SELECT * from rstSwift WHERE rstSwift.Date = #20/11/2011#")
Do While Not rstSwift.EOF
   INSERTFUNCTIONHERE
   rstSwift.MoveNext
Loop

Это может быть быстрее, чем то, что вы используете в настоящее время, в зависимости от того, сколько записей соответствует фильтру.

СЛОВО ОСТОРОЖНО:
Приведенный мною пример может быть подвержен атакам SQL-инъекций, если вы модифицируете запрос, который будет создаваться динамически на основе какого-либо ввода. ВСЕГДА убедитесь, что вы очищаете свой SQL перед запуском.

...