Rambler's Top100
Форум: MS ACCESSVBVBA MS OfficeMS SQL server
Новые сообщения: 0000

Форум: MS ACCESS

Вопросы связанные с MS ACCESS

Обновить визитку
Участники «Online»
Все участники

 
 

Доброго времени суток, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: подзапросы...
 
 автор: osmor   (16.06.2009 в 12:47)   личное сообщение
 
 

MSA 2003
Суть:
Есть таблица около 500'000 записей
В ней текстовое поле (URN) 255 символов
поле может быть как пустым так и нет
Нужно НЕ пустые поля проверить на соответствие определенным условиям и в случае НЕ соответствия изменить поле TypeError в этой же таблице.
Условия сложные (используются RegExp), по-этому проверка вынесена в функцию ( checkURN). Работает не быстро.
Что бы ускорить, хочу отправлять на проверку в функцию ТОЛЬКО те записи где поле URN не пустое.
Пишу:

UPDATE (
                    SELECT ostmp_tblObject.typeError, 
                                    ostmp_tblObject.URN 
                    FROM ostmp_tblObject 
                   WHERE (nz([URN],"")<>"")
                 )  AS s1 
SET s1.typeError = "URN IS INVALID"
WHERE checkURN([URN])=False;

Один фиг в функцию идут и записи с пустыми значениями, т.е. во внешнем запросе обрабатываются все записи из таблицы, а не только те которые должны попасть во внутренний ....WHERE (nz([URN],"")<>"")
По некоторым причинам использовать сохраненный запрос не могу... т.е. не хотел бы
Вопрос:
Что делать!!!?

  Ответить  
 
 автор: Кабан   (16.06.2009 в 13:05)   личное сообщение
 
 

может len(nz([URN],""))<>0

я бы так писал
UPDATE ( 
                    SELECT ostmp_tblObject.typeError,  
                                    ostmp_tblObject.URN  
                    FROM ostmp_tblObject  
                   WHERE len(nz(ostmp_tblObject.URN,""))<>0
                 )  AS s1  
SET s1.typeError = "URN IS INVALID" 
WHERE checkURN(s1.[URN])=False; 

  Ответить  
 
 автор: osmor   (16.06.2009 в 14:30)   личное сообщение
 
 

не прокатило.

  Ответить  
 
 автор: Lukas   (16.06.2009 в 13:09)   личное сообщение
 
 

В таком варианте функция вызывается только для непустых URN:


UPDATE (SELECT ostmp_tblObject.typeError,  ostmp_tblObject.URN FROM ostmp_tblObject WHERE checkURN([URN])=False AND Len([URN] & "")>0 ) AS s1 
SET s1.typeError = "URN IS INVALID";


Если условие переписать так (почти то же самое, казалось-бы)

WHERE Len([URN] & "")>0  AND checkURN([URN])=False

То функция будет вызвана для всех значений URN

  Ответить  
 
 автор: osmor   (16.06.2009 в 14:25)   личное сообщение
 
 

во блин... или я этого не знал или основательно забыл...
тогда можно и вообще без подзапроса

UPDATE 
              ostmp_tblObject 
SET ostmp_tblObject.URN = "URN IS INVALID"
 
WHERE (checkURN([URN])=False) and (len(URN & "")>0) ;

Забыл... СПАСИБО!!!

  Ответить  
 
 автор: Анатолий (Киев)   (16.06.2009 в 14:07)   личное сообщение
 
 

А что, поле [URN] допускает пустые строки?
Если только Null то: WHERE ([URN] Is Not Null)
Если допускает, то: WHERE ([URN] Is Not Null And [URN]<>'')

Но всё это имеет смысл, если поле индексированное а таких значений много, иначе лучше обойтись без вложенного запроса, аргумент функции сделать типа Variant, а первой строкой функции проверять на "пустоту", возвращать True и прерывать функцию.

Если есть возможность какие-то условия проверить с помощью Like, лучше добавить его в WHERE перед функцией.

Удачи, Олег!

  Ответить  
 
 автор: osmor   (16.06.2009 в 14:29)   личное сообщение
 
 

Спасибо.
Это поле появляется из текстового файла... который в свою очередь появляется в результате работы некого стороннего, закрытого скрипта, который "шестит" недра интернета и выбирает фразы по ключевым наборам слов.
т.е. вероятно что может быть и NUll и vbNullString

  Ответить  
 
 автор: osmor   (16.06.2009 в 14:32)   личное сообщение
 
 

Спасибо всем прочитавшим. Огромное спасибо откликнувшимся.
Вопрос решен "методом Лукаса", т.е. условие с функцией ставится первым.

  Ответить  
 
 автор: АлексейЕ   (16.06.2009 в 17:17)   личное сообщение
 
 

Пусть я и Опаздун, но задел меня вопрос твой, Олег. Решил поразбираться и понять, как эти запросы в Access работают.
Может, кому и пригодится.

Для начала, если твой запрос привести к такому виду,
UPDATE ( 
                    SELECT ostmp_tblObject.typeError,  
                                    ostmp_tblObject.URN  
                    FROM ostmp_tblObject  
                   WHERE checkURN([URN])=False  
                 )  AS s1  
SET s1.typeError = "URN IS INVALID" 
WHERE  (nz([URN],"")<>"") ; 


То, как ни странно, он отработает, так как ты хочешь. (теоретически, т.к. я тестил на другой таблице)

Подключил недокументированную фичу от Microsoft – запись в текстовой файл плана выполнения запроса Jet'ом.
Подергался и вот мои выводы.

1. Если обращение идет, в итоге, к одной и той же таблице, что у основного запроса, что и у вложенного, то Jet приведет такой запрос к запросу без вложенного, т.е. сделает общий Where, что б не шерстить основную таблицу, а затем выборку. Одним махом так, шмяк и выполнил.

Но этот общий Where он формирует таким образом, сначала условие основного запроса And условие вложенного.
Оказалось, так же, что у Jet'а куча комплексов (совсем как у людей).
а) Он «боится» знака неравно '<>', если он встречает такой оператор, то он его переделает в '=' и перед поставит NOT (Но оно наверно и логично, хотя…)
б) Он ненавидит True. Опять же, если встречает, то все сделает, что бы было сравнение с 0. Видимо это связано с тем, что в MS SQL True = 1. Вот, что бы не заморачиваться определением кто представляет данные он с 0 и сравнивает всегда

И так, в твоем варианте, Олег, Jet, по идее, должен сделать такое условие.

"checkURN([URN])= 0 And Not nz([URN],"")=""" (шерстит все строки и [URN] пустое)

В варианте же, который я указал, получим такой план

" Not nz([URN],"")="" And checkURN([URN])=0" (то что нужно)


2. Казалось бы, это противоречит тому, что написал Лукас... Так вот нет, ни капельки. Ведь я выше продемонстрировал, в каком порядке Jet проверяет условие у себя, в нутрях, а не как отображает нам в окне построения запросов.
Если так же просмотреть в плане выполнения запросы Лукаса, то окажется, что Jet его перевернет с ног на голову.
Т.е. в построителе запросов
WHERE checkURN([URN])=False AND Len([URN] & "")>0 )
В плане запросов, что типа
Restrict rows of table Таблица by scanning testing expression "Not Len([URN] & "")=0 And checkURN([URN])=0"

Одного я не понял, если он объединяет в единое условие, и объединяет с помощью AND , то, по идее, согласно человеческой логике, независимо от места положения функции checkURN () она должна отрабатывать всегда… Почему не отрабатывает?
Загадка.

  Ответить  
 
 автор: Lukas   (16.06.2009 в 18:48)   личное сообщение
 
 


Почему не отрабатывает?


Имея условие: ВыражениеA And ВыражениеB, сначала вычисляется одно из выражений и в зависимости от полученного результата принимается решение о вычислении второго выражения.
Для False And Выражение2 вычислять второе выражение бессмысленно (и оно не вычисляется),
для True And Выражение2 вычисление второго выражения необходимо (и оно вычисляется).

Public Function Test() As Boolean
'    Test = True And Len(Null) = 0 '    ?Test()=>"Run-time Error 94, Invalid use of Null"
'    Test = False And Len(Null) = 0 '   ?Test()=>False

'Для OR соответственно обратная логика:
'    Test = True Or Len(Null) = 0          '?Test()=>True
'    Test = False Or Len(Null) = 0         '?Test()=>"Run-time Error 94, Invalid use of Null"
End Function

Если в плане выполнения первым выражением идет Not Len([URN] & "")=0 , то видимо оно и вычисляется первым.

  Ответить  
 
 автор: Lukas   (16.06.2009 в 20:21)   личное сообщение
 
 


Может, кому и пригодится.


Мне п.1 внушает оптимизм.
Интересен такой момент:
Я использую SQL-строку "Select * From (имя сохраненного запроса с Join-ами разных таблиц) Where ... Order By..."
Как Jet приводит такие запросы в плане выполнения, как в п.1 (абзац 1) или иначе?
Если будет возможность и желание глянуть, огласите результаты плиз. Спасибо.

  Ответить  
 
 автор: osmor   (17.06.2009 в 08:57)   личное сообщение
 
 

Алексей, мне тоже это очень интересно, но я сейчас в жутком цейтноте (в общем как всегда).
Через неделю в отпуск, надо много всего сделать.
Если что найдешь интересное - пиши сюда.
В отпуске почитаю повнимательней (если будет wi-fi)

  Ответить  
HiProg.com - Технологии программирования
Rambler's Top100 TopList