Форум программистов, компьютерный форум, киберфорум
Visual Basic
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 Аватар для BasicMan
19318 / 2625 / 84
Регистрация: 17.02.2009
Сообщений: 30,364

Приемы взаимодействия Visual Basic и SQL

22.05.2009, 17:54. Показов 22336. Ответов 0
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
При создании приложений, оперирующих базами данных, нередко возникают проблемы, связанные с организацией взаимодействия языка программирования с языком SQL. В статье раскрываются приемы использования SQL-запросов при работе Visual Basic 6.0 с библиотекой Microsoft DAO 3.51 Object Library.

Применение SQL-запросов в коде программы, работающей с базой данных, имеет свои преимущества — это просто, наглядно и весьма эффективно. Однако из-за различия типов данных Visual Basic и SQL при передаче переменных из кода программы в SQL-запрос могут возникать неприятные нюансы.

Начнем с простого случая. Предположим, что у нас имеется база данных, хранящаяся в файле DataBase. mdb, и в ней есть таблица tblAdres с полями fieldCity, fieldStreet, fieldHouse, fieldSurname и fieldTelefon. Требуется выбрать записи адресатов, проживающих, например, во Владивостоке.
Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Dim db As Database
'во всех примерах используется Microsoft DAO 3.51 Object Library
Dim rs As recordset
'в последующих примерах (для экономии места)
'эти переменные не будут объявлены
Set db = OpenDatabase (App.Path & "DataBase.mdb")
Set rs = db.OpenRecordset ("SELECT * FROM [tblAdres] WHERE [fieldCity] = Владивосток")
Do Until rs.EOF
'предполагается, что в наличии есть элемент управления ListBox1,
'куда мы и будем передавать записи
ListBox1.AddItem rs.Fields("fieldCity") & " " & rs.Fields("fieldStreet") & " " & _
rs.Fields("fieldHouse")& " " & _
rs.Fields("fieldSurname") & " " & rs.Fields("fieldTelefon") & vbCrLf
rs.MoveNext
Loop 'в последующих примерах эти операторы будут опущены
rs.Close
Set rs = Nothing
db.Close
Set db = Nothing
Весь запрос заключен в двойные кавычки. Чтобы процессор БД «выявил» наличие в запросе переменной, ее следует вывести за кавычки. В нашем случае это делается так:
Visual Basic
1
2
3
4
5
6
Dim db As Database
Dim rs As Recordset
Dim strCity As String
StrCity = "Владивосток"
Set db = OpenDatabase (App.Path & "DataBase.mdb")
Set rs = db.OpenRecordset ("SELECT * FROM [tblAdres] WHERE [fieldCity] = " & strCity)
Данный запрос уже близок к готовности, но если вы попытаетесь его применить, то, скорее всего, получите сообщение об ошибке № 3061: Too few parameters. Expected 1. («Слишком мало параметров. Ожидался один»). Дело в том, что перед тем, как передать строковую переменную в SQL-запрос, ее нужно ограничить одинарными кавычками, для чего Дж. Мак-Манус рекомендует соответствующую функцию (Джеффри П. Мак-Манус. Обработка баз данных на Visual Basic 6. М.: Диалектика, 1999).
Visual Basic
1
2
3
Private Function Quote(strVariable As String) As String
   Quote = "'" & strVariable & "'"
End Function
Это особенно удобно тогда, когда приходится передавать несколько строковых переменных в различные запросы. Итак, наш запрос примет вид:
Visual Basic
1
Set rs = db.OpenRecordset ("SELECT * FROM [tblAdres] WHERE [fieldCity] = " & Quote(strCity))
Данная строка кода, конечно, работает, но только нужно будет добавить в проект функцию Quote, а если вы не хотите это делать, то достаточно слегка «модернизировать» переменную strCity:
Visual Basic
1
2
3
strCity = "Владивосток"
strCity = "'" & StrCity & "'"
Set rs = db.OpenRecordset ("SELECT * FROM [tblAdres] WHERE [fieldCity] = " & strCity)
Теперь о том, как передать в запрос несколько переменных. Допустим, требуется выбрать записи по жителям Владивостока, носящим фамилию Иванов.
Visual Basic
1
2
3
4
5
6
7
8
Dim strCity As String
Dim strSurname As String
Dim strSQL As String
strCity = "Владивосток"
strSurname = "Иванов"
strSQL = "SELECT * FROM [tblAdres] WHERE [fieldCity] = " & Quote(strCity) & _
" AND [fieldSurname] = " & Quote(strSurname)
Set rs = db.OpenRecordset(strSQL)
Строка запроса несколько усложнилась, но ее структура осталась такой же. В подобных случаях целесообразно разбить строку на несколько частей, иначе она не поместится на экране и работать с ней будет неудобно. Рекомендую разделить ее так, чтобы каждая SQL-директива находилась на новой строке. Это упростит редактирование запроса и поиск в нем ошибок.
Visual Basic
1
2
3
4
5
strSQL = "SELECT * " & _
"FROM [tblAdres] " & _
"WHERE [fieldCity] = " & Quote(strCity) & _
"AND [fieldSurname] = " & Quote(strSurname)
Set rs = db.OpenRecordset(strSQL)
Обратите внимание на пробел между кавычками и директивой AND. В случае использования переменных в запросе порой трудно понять, зачем он нужен, но без него вы получите сообщение об ошибке № 3131: Syntax error in FROM clause («Синтаксическая ошибка в пункте FROM»). Действительно, если еще раз взглянуть на SQL-запрос, написанный в одну строку (см. предыдущий пример), то нетрудно заметить, что без этого пробела директива AND «прилипнет» к переменной Quote(strCity) и приведет к ошибке. Чтобы оградить себя от подобных проблем, рекомендую ставить пробел перед всеми SQL-директивами.

Теперь посмотрим, как можно применить переменную в названии таблицы или поля, особенно если в этом названии имеются пробелы. Ограничить их одинарными кавычками не удастся — поступит сообщение об ошибке № 3450: Syntax error in query. Incomplete query clause («Синтаксическая ошибка в запросе. Неполная строка запроса»). В этом случае с помощью той же конкатенации строк нужно заключить переменную в квадратные скобки. Пусть наша таблица называется [tbl Adres] и имеет поля [field Surname], [field City], [field Street], [field House]. Нам потребуется выбрать адреса граждан c определенной фамилией, проживающих в городе, указанном пользователем. Добавим также в проект текстовые поля: txtPeople и txtCity. Как несложно увидеть, SQL-запрос полностью состоит из переменных (кроме директив самого запроса).
Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
Dim strTable As String
Dim strFieldPeople As String
Dim strFieldCity As String
Dim strFieldStreet As String
Dim strFieldHouse As String
Dim strPeople As String
Dim strCity As String
strTable = "[tbl Adres]" 'наименование таблицы
strFieldPeople = "[field Surname]"
'наименование поля таблицы ‘Фамилия’
strFieldCity = "[field City]"
'наименование поля таблицы ‘Город’
strFieldStreet = "[field Street]"
'наименование поля таблицы ‘Улица’
strFieldHouse = "[field House]"
'наименование поля таблицы ‘Дом’
strPeople = Trim(txtPeople.Text)
'даем возможность ввести критерии выборки,
strCity = Trim(txtCity.Text)
'и сразу отсекаем лишние пробелы
Set rs = db.OpenRecordset("SELECT " & strFieldStreet & "," & strFieldHouse & _
" FROM " & strTable & _
" WHERE " & strFieldPeople & "=" & Quote(strPeople) & _
" AND " & strFieldCity & “=“ & Quote(strCity))
Рассмотрим еще несколько примеров. Допустим, у нас есть база данных, включающая таблицу tblOperations с полями [fieldNumber], [fieldData], [fieldNameCompany] и [fieldSum]. Первое поле содержит номер заказа, второе — дату, третье — имя компании, четвертое — сумму операции. Необходимо сформировать критерии выборки по имени компании, причем если поле не заполнено, то recordset должен включать полный набор записей, а если заполнено, — то и критерий выборки. В последнем случае вполне можно обойтись одним SQL-запросом. Опишем подробнее процесс формирования критерия. «Нарисуем» в форме текстовое поле txtCompanyName.
Visual Basic
1
2
3
4
5
6
7
8
9
10
Dim strCompanyName As String
If txtCompanyName.Text <> Empty Then
   strCompanyName = "=" & Quote(txtCompanyName.Text)
Else
   strCompanyName = "is not Null"
'если, конечно, вы уверены, что 
'в базе данных нет пустых записей
End If
Set rs.OpenDatabase ("SELECT * " & “ FROM tblOperations " & _
" WHERE [fieldNameCompany] " & strCompanyName)
Если текстовое поле txtCompanyName не будет заполнено, то приведенный код программы выберет все записи таблицы. А если его заполнить, то recordset станет выбирать записи по критерию совпадения со значением, введенным в поле txtCompanyName. О том, как выполнить выборку по дате, расскажем чуть ниже, а теперь вернемся к приведенному примеру. Обратите внимание, что в запросе между директивой WHERE [fieldNameCompany] и переменной нет математического знака — он выносится за пределы запроса и становится частью переменной. Важно знать, что процессор баз данных интерпретирует пустое поле таблицы как Null, а не как Empty, и потому нельзя использовать значение Empty при работе с базами данных.

В одном из приведенных примеров мы уже присваивали строковой переменной весь SQL-запрос. То же самое допустимо выполнить с любой частью этого запроса, в том числе с включающей директивы SQL. Вот как в таком случае будет выглядеть предыдущий пример:
Visual Basic
1
2
3
4
5
6
7
8
9
10
Dim strCompanyName As String
If txtCompanyName.Text <> Empty Then
    strCompanyName = " WHERE [fieldNameCompany] = " & Quote(txtCompanyName.Text)
Else
    strCompanyName = " WHERE [fieldNameCompany] IS NOT Null" 
End If
 
Set rs.OpenDatabase ("SELECT * " & _
    " FROM tblOperations " & _
    strCompanyName)
В поле нашего зрения находятся преимущественно строковые переменные. Дело в том, что кроме них передать в SQL-запрос можно только переменные типа byte, integer и long. Все же остальное придется переводить именно в строковый тип. Поэкспериментируем с переменными типа integer немного позже, а сначала посмотрим, как проще всего перевести переменную в строковый тип.

Для переменных single, double и currency имеет смысл применить встроенную функцию преобразования в строковый вид str(variable).
Visual Basic
1
2
3
4
5
Dim curPrice As Currency
Dim strPrice As String
curPrice = 44.56
strPrice = str(curPrice)
'не забудьте заключить ее в одинарные скобки
Когда требуется сделать выборку данных по полю, содержащему логические значения, иногда бывает необходимо применить в запросе переменную типа boolean. Для этого можно использовать функцию IIf. Если переменная содержит значение True, то функция вернет строковое значение «True», и наоборот.
Visual Basic
1
2
3
4
5
Dim varBoolean As Boolean
varBoolean = True
Set rs.OpenDatabase ("SELECT * " & 
    "FROM [tblAdres] "  &  _
    "WHERE [fieldGood] = " & IIf(varBoolean,    "True", "False")
В итоге переменную типа date придется также передавать как строковую переменную с учетом ее собственного формата. Дата передается в SQL-запрос как #dd/mm/yy#, поэтому нужно собрать и строковую переменную. Обратите внимание, что даже если в операционной системе формат даты установлен с разделителями в виде точек, отображающихся в полях базы данных, формат переменной, передаваемой в SQL-запрос, все равно должен иметь косую в качестве разделителя.
Visual Basic
1
2
3
4
5
Dim strDate As String
strDate = "#27/08/2002#"
Set rs.OpenDatabase ("SELECT * " & _
    "FROM tblOperations " & _
    "WHERE [fieldDate] = " & strDate)
Как вариант, в поле базы данных, куда будет заноситься дата, можно поставить текстовый тип этого поля и работать только со строковыми переменными. Следует помнить, что переменная типа date занимает 8 байт, а переменная типа string — 10 байт плюс длина строки.
Visual Basic
1
2
3
4
5
6
7
8
Dim intTable As Integer
For intTable = 1 To 5
    Set rs.OpenDatabase ("SELECT * " & "FROM " & intTable)
    Do Until rs.EOF
    LisBox1(intTable - 1).AddItem rs.Fields("field1")   & " " & vbCrLf
    rs.MoveNex
Loop
Next intTable
Теперь рассмотрим переменные типа byte, integer и long, которые не требуется обязательно обрамлять одинарными кавычками. Предположим, у нас есть база данных с несколькими таблицами, носящими имена 1, 2, 3, 4, 5. Нужно выбрать из всех таблиц данные и разнести их по разным элементам отображения. Создадим пять экземпляров элемента управления ListBox с одинаковым названием и индексами от 0 до 4. Вот как будет выглядеть наш код:
Visual Basic
1
2
3
4
5
6
7
8
9
10
Dim intField As Integer
Dim strField As String
For intField = 1 To 3
    strField = "[field" & intField & "]"
Set rs.OpenDatabase ("SELECT " & Quote(strField ) & " FROM [tbl1]")
Do Until rs.EOF
    LisBox1(intField).AddItem rs.Fields("field1") & " " & vbCrLf
rs.MoveNex
Loop
Next intField
Данный код пять раз выберет набор записей и разнесет его по различным элементам. То же самое можно сделать и с полями таблицы, если в их названии присутствуют последовательные целые числа. Если имена таблицы или ее полей более сложны, то можно «собрать» их имя в строковую переменную путем конкатенации. Пусть в таблице tbl1 имеются поля: [field 1], [field 2], [field 3]. Тогда выборку из нее можно сделать с помощью кода:

Применение переменных при организации связи языка программирования с SQL существенно повышает гибкость программы. Вам достаточно будет написать одну процедуру с правильно организованным запросом, и тогда вы сможете просто вызывать ее, передавая переменные в качестве параметров. Таким образом вы уменьшите свой код и повысите продуктивность его использования.

Евгений Немец 20.10.2002
Мир ПК, #10/2002
12
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
22.05.2009, 17:54
Ответы с готовыми решениями:

Visual basic & SQL
Доброго времени суток. Такой вопрос меня мучает уже более суток. Имеется одна большая бд (я выбрал на sql) Там столбцы (их много) ...

Запросы sql в visual basic
не могу понять!!! Почему то запросы с условиями работают только если тип поля в условии является числовым, если его тип текстовый то...

Sql server и VS visual basic. Авторизация
Есть 3 формы. 1 форма - форма авторизации. (на форме расположены Text.box1 и Text.box2 соответственно логин и пароль и кнопка...

0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
22.05.2009, 17:54
Помогаю со студенческими работами здесь

Sql server и VS visual basic. Авторизация
Здравствуйте :) Помогите пожалуйста. Нужно создать авторизацию. Есть форма, на форме 2 textbox-а и 2 label-а соответственно(Емайл и...

Visual Basic 6.0. + SQL Server 2012
Добрый день, уважаемые. Очень нужна ваша помощь. Подскажите, пожалуйста. Есть база данных SQL Server 2012. В ней таблица MARA и...

SQL запрос BETWEEN две переменные :( Visual Basic
у меня есть база данных в ней таблица tblBuy в таблице есть поле Date_Buy есть две переменных date_from и date_to как должен выглядеть...

Вычисление значений функции двух переменных в Visual Basic - Visual Basic
Помогите пожалуйста! В среде VB написать программу вычисления значений функции двух переменных. Ориентировочный вид окна программы и...

Где бесплатно скачать учебник по Visual Basic 6 и Visual Basic .Net ?
Где бесплатно скачать учебник по Visual Basic 6 и Visual Basic .Net


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
1
Закрытая тема Создать тему
Новые блоги и статьи
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru