Программное выполнение запроса с параметром по SQL-тексту

VBA2007
Дата: 27.02.2008 20:46:19
Можно ли на лету создать параметризованный запрос по тексту SQL (QueryDef с Parameters без сохранения в базе).

Или единственный способ - 1 раз создать и хранить в базе, а потом его использовать.
Karfaqen
Дата: 27.02.2008 21:24:38
А если "на лету" да "без сохранения в базе", зачем вообще QueryDef?
Select прямо в источник можно подставить, Recordset на нем открыть.
Исполняемым - сразу делать Execute.
Что за запрос у вас?
Karfaqen
Дата: 27.02.2008 21:28:10
Опять же, если "на лету", то в текст запроса проще вставлять НЕ формальный параметр, а прямо сразу его значение, да и все.
VBA2007
Дата: 27.02.2008 21:59:10
Вопрос снят.

QueryDef нельзя создавать через New (вернее толку от него будет мало - не видит параметры).

Временный запрос (без сохранения в базе) можно создать, указав пустую строку в кач-ве имени запроса:

Set qdfQuery = db.CreateQueryDef("", SQLText)
VBA2007
Дата: 27.02.2008 22:01:26
Karfaqen
А если "на лету" да "без сохранения в базе", зачем вообще QueryDef?
Select прямо в источник можно подставить, Recordset на нем открыть.
Исполняемым - сразу делать Execute.
Что за запрос у вас?


Мне привычнее указывать параметры не тексте SQL запроса.
Программист-Любитель
Дата: 28.02.2008 08:38:47
А зачем ? Вместо одной строчки сборки SQL строки и ее выполнения CurrentProject.Connection.Execute "SELECT ... FROM ... WHERE ..." придется писать много. Да и динамическая сборка SQL гораздо гибче и шире по возможностям нежели простановка параметров в запрос жесткой структуры.
alexmsp
Дата: 28.02.2008 09:32:57
Программист-Любитель
А зачем ? Вместо одной строчки сборки SQL строки и ее выполнения CurrentProject.Connection.Execute "SELECT ... FROM ... WHERE ..." придется писать много. Да и динамическая сборка SQL гораздо гибче и шире по возможностям нежели простановка параметров в запрос жесткой структуры.

+1
Сам вопрос как уже Karfaqen заявил не имеет смысла.
Сохраненный вопрос с параметрами имеет смысл если вызывается не в первый раз (т.е. уже оптимизирован по быстродействию). А если в первый то лучше сразу текст пихать.ИМХО.
Анатолий ( Киев )
Дата: 28.02.2008 12:23:07
[quot Karfaqen и другие коллеги]А если "на лету" да "без сохранения в базе", зачем вообще QueryDef?
Опять же, если "на лету", то в текст запроса проще вставлять НЕ формальный параметр, а прямо сразу его значение.
[quot]Позвольте не согласиться. В некоторых случаях временный запрос с параметрами (особенно, если явно описан их тип) очень даже полезен.
1. Когда он выполняется в цикле при перемещении по другому RS. Второй раз и далее он выполняется быстее, да и процедура выглядит красивше. Сам запрос создается где-то в начале процедуры, а в цикле - подстановка параметров и выполнение;
2. Значение даты или дробное число передается прямо в параметр без приведения к специальному формату;
3. Для строковых критериев не надо заботиться о дублировании кавычек внутри текста.
Karfaqen
Дата: 28.02.2008 14:25:50
2Анатолий
Вобщем тут и я могу согласиться с вами, хотя большинство замечаний насчет "простоты" того или иного варианта - это, скорее, вопрос общей программной организации и наличия/отсутствия каких-то своих процедур, которые умеют "позаботиться" в том числе и по упомянутым пунктам.

Ну кроме одного обозначенного вами момента, который такими "своими" средствами не решается:
Анатолий ( Киев )
в цикле ... второй раз и далее он выполняется быстее
Речь о том, что в случае создания временного querydef запрос будет компилированным? Мне вот как-то не пришлось сравнить быстродействие, скажем сохраненного update, и написанного строкой в коде. Если вам доводилось это делать, может вкратце скажете по своему опыту, насколько вообще значителен выигрыш во времени выполнения в подобном случае?
Анатолий ( Киев )
Дата: 28.02.2008 17:56:02
Karfaqen
сравнить быстродействие, скажем сохраненного update, и написанного строкой в коде
ИМХО львиную долю времени на выполнение запроса забирают дисковые операции, особенно, если данные в большом объеме таскаются по сети. Поэтому преимуществом в быстродействии сохраненного запроса можно пренебречь, тем более, что (из умных книжек):
- Запрос с использованием VB функций сохраняется нескомпилированным;
- Оптимальный план на момент первого вызова запроса может оказаться не лучшим при увеличении объема данных, изменении индексов, и т.д.
Karfaqen
Речь о том, что в случае создания временного querydef запрос будет компилированным? Насколько вообще значителен выигрыш во времени
Вот процедурка, сравнивающая время обработки запросов из родной таблицы в 2-х вариантах по 1000 раз:
Sub TestQuerySpeed()
Dim t(1 To 4) As Single, i As Integer
Dim sSQL As String, db As DAO.Database, qdf As DAO.QueryDef, rst As DAO.Recordset
Const Cycle = 1000

    sSQL = "SELECT * FROM TempTable WHERE (((ID)=1));"

    Set db = CurrentDb
    Set qdf = db.CreateQueryDef("", sSQL)
 
    Set rst = qdf.OpenRecordset
    t(1) = Timer
 For i = 1 To Cycle
    Set rst = qdf.OpenRecordset
 Next
    t(2) = Timer
    
    t(3) = Timer
 For i = 1 To Cycle
    Set rst = db.OpenRecordset(sSQL)
 Next
    t(4) = Timer

MsgBox t(2) - t(1) & vbCrLf & t(4) - t(3)
End Sub
Средний результат: 2,47 сек - 2,55 сек. Т.е. в тепличных условиях использование временного запроса предпочтительнее db.OpenRecordset(sSQL), но на сущую ерунду.
Не знаю, составляет ли qdf оптимальный план (т.е. компилируется), но при его объявлении SQL выражение дерибанится, т.к. его св-во Fields возвращает семейство полей. Т.е. 1 раз против 1000.
Вывод - не стОит этим заморачиваться.