Архив метки: vba

Как научиться SQL?

Ресурсы которые стоит почитать:
http://www.sql-tutorial.ru/ru/content.html
http://www.sql.ru/docs/sql/u_sql/index.shtml

По 2 ссылке онлайн версия книги «Понимание SQL» Мартина Грабера. Она же в FB2 формате, для прочтения офлайн:

Gruber_Ponimanie-SQL

И еще 1 очень неплохая книга для самоподготовки по SQL:

rukovodstvo_SQL

Для того чтобы суметь написать запрос и понимать как он отработает необходимо знать и понимать что означают следующие ключевые слова в синтаксисе SQL.

SELECT
INSERT
UPDATE
DELETE
FROM
GROUP BY
WHERE
HAVING
INNER JOIN
ORDER BY
UNION
DISTINCT

Нужно понимать что вариаций SQL очень много, практически в каждой БД используется своя модификация, которая часто очень сильно увеличивает возможности базового языка. Для оптимизации своего рабочего места обычно используется Excel или Access, в которых использована модификация Jet SQL. Она приближена к стандарту ANSI для SQL (общий стандарт — запросы написанные на котором должны выполняться на любой его модификации), который в книгах обычно и описывают, и позволяет использовать некоторые встроенные функции VBA.

Небольшое задание для самоподготовки. В нашем отделе используется для определения уровня знания SQL при приеме на работу новых кандидатов.

Нужно рассказать что делает запрос.
1(простая выборка) — элементарный уровень ,
2(объединение таблиц) и 3(группировки) — базовый уровень,
4(все из предыдущих, используемое совместно + параметры) в дополнении к описанию нужно исправить 4 умышленные ошибки — расширенный уровень.

1)
select * from vw_income_docs as v where v.tpdprt=706 and v.id > 24485911073 order by v.id

2)
select t1.e_collection, t1.e_tma_category, t1.e_tma_tm, t1.e_tma_ware_subgroup, k.code_model,t1.moniker from
(select t.e_collection, t.e_tma_category, t.e_tma_tm, t.e_tma_ware_subgroup, t.id_mmodel,t.moniker from VW_WARE as t
where t.moniker like «CMT703T0*») as t1 inner join vx_model as k on k.id_model=t1.id_mmodel

3)
select count(t1.FirstQ) as kolvoM from (SELECT First(QuotaAW1213.Quota) AS [FirstQ]
FROM QuotaAW1213
GROUP BY QuotaAW1213.ShopID
HAVING (((First(QuotaAW1213.Quota))=»A1″))) as t1

4)
PARAMETERS dateBegin DateTime, tm Text ( 255 ), TGroup Text ( 255 ), Divs Text ( 255 ) ;
SELECT t2.model, t4.TM, t2.name, t2.TPGroup, t2.price, t3.Nshop, t3.upa, t1.date, t1.type, t1.pf, t1.plan
FROM ((
select ph, [date], ‘продажи ОЦ’, ‘факт’, RSumm from tren_prod where [date] between [dateBegin] and [dateEnd] and [Division]=[Divs]
union all
select ph, [date], ‘продажи РРЦ’ as type, ‘план’ as pf, plan*price from tren_plan_zakaz_union where [date] between [dateBegin] and [dateEnd] and [Division]=[Divs]
union all
select ph, [date], ‘продажи ОЦ’ as type, ‘план’ as pf, plan*price*(1-discount) from tren_plan_zakaz_union where [date] between [dateBegin] and [dateEnd] and [Division]=[Divs]
) AS t1
INNER JOIN (SELECT max(Nshop_tren.Nshop) AS Nshop, max(Nshop_tren.pres) FROM Nshop_tren WHERE Division=RD GROUP BY ph) AS t3 ON t1.ph = t3.ph) INNER JOIN tmp_art AS t2 ON t1.ph = t2.PH
WHERE (t2.RD=TRUE OR t2.DD=true) AND t2.TM=[tm] AND (t2.Group=[TGroup] or t2.Cat=[TGroup]);

Запуск SQL запросов из VBA для Access и Excel

sql-fun
sql-fun
В различных ситуация требуется какое либо действие сделать с БД с помощью SQL запросов, и при написании программы зачастую требуется это сделать из VBA кода. Для этого я использую различные схемы, в зависимости от сложности запроса и поставленной задачи.
, где для всех примеров myBD это объявленная наша БД, например через Dim myBD As Database и последующей Set myBD = CurrentDb , как пример для Access

 

1 — Запуск запросов через QueryDef, ИМХО — использую для ODBC:
Для первого варианта средствами Access делаем обычный запрос  с нужными нами действиями или несколько связанных между собой и запускаем его строчкой ниже. Вообще QueryDef является одним из лучших методов по запуску и выполнению (да запуск сохраненных SQl запросов через него, это далеко не все что он может) запросов в базах данных использующих драйвер ODBC.
myBD.QueryDefs(«ИМЯ_ЗАПРОСА»).Execute
или делаем непосредственный запуск запроса
myBD.QueryDefs.Execute «DELETE * FROM MyTabl»

 

2 — Запуск запросов через RecordSet, ИМХО — использую для ADO:
Этот вариант у меня прижился больше для Excel когда к БД подключаюсь через ADO драйвер, и требуется например сохранить данные в бд, через запрос (Помидорами не кидать, знаю что сам RecordSet позволяет это делать — тут просто пример как можно запустить запрос через него)
Set rs = cmd.Execute(«DELETE * FROM MyTabl», , adExecuteNoRecords)

 

3 — Непосредственный запуск запросов
ИМХО — использовать стоит в основном внутри Access и довольно редко, для мелких задач, а для всего отсльаного лучше через QueryDef:
DoCmd.RunSQL «DELETE * FROM MyTabl»
myBD.Execute «DELETE * FROM MyTabl»

При выполнении SQL запроса из VBA кода, в месте где пишется условие, при использовании сравнения LIKE нужно использовать символ %, а не когда требуется сравнивать какую то часть текста, а не точное сравнение. При этом если запустить запрос с * например в Access,  то он отработает нормально. Если не знать эту особенность, то ошибку можно долго искать в коде.

Правильно :  SELECT * FROM table WHERE pole LIKE «%Условие%»

НеправильноSELECT * FROM table WHERE pole LIKE «*Условие*»