Выбор из нескольких таблиц в VBScript / ASP - PullRequest
1 голос
/ 07 декабря 2011

Я понимаю, что этот вопрос основан на очень старом языке программирования, а также на некоторых неэффективных методах проектирования баз данных, но я надеюсь на некоторые рекомендации, так как мой VBScript не с нуля, и на своей работе я я не могу изменить структуру базы данных или язык сценариев.

Я работаю над веб-страницей, которая получает свои данные из базы данных, которая изначально содержала все свои данные в одной таблице. Однако менеджеры баз данных в моей работе решили разбить большую таблицу на множество более мелких. Наша веб-страница содержит онлайн-карту с данными о точках, которая отображает на новой странице таблицу данных для каждой найденной точки. Код для подключения к базе данных изначально выглядел примерно так:

sql_select = "SELECT * FROM table_name WHERE master_id='"&key&"'"
Set rs = Conn.Execute(sql_select)

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

Мне кажется, что я понимаю теорию о том, как сделать эту работу (я не специалист по информатике, так что это все еще несколько чуждо мне), и что мне нужно создать профсоюз. Моя основная проблема связана с синтаксисом VBScript / ASP при создании этого скрипта, поскольку кажется, что все, что я пытаюсь, не работает.

Кто-нибудь может дать мне какое-нибудь руководство? Очень ценится!

Ответы [ 2 ]

3 голосов
/ 08 декабря 2011

Похоже, что вам на самом деле нужно присоединиться, а не союз.JOIN склеивает данные из нескольких мест в одну строку, а UNION склеивает несколько строк данных в набор из нескольких строк:

Запрос к базе данных

В этом случае у вас естьглавная таблица и несколько вспомогательных таблиц.Для примера я предположу, что таблицы выглядят следующим образом:

Table         Columns
---------------------------
MasterTable   MasterId, M1, M2, M3
SubTableA     SubTableAId, MasterId, A1, A2, A3
SubTableB     SubTableBId, MasterId, B1, B2, B3

Так что, если вы хотите получить столбцы M1-3 и A1-A3, вы можете объединить столбцы из MasterTable со столбцами наSubTableA, где они имеют совпадающие значения MasterId:

SELECT *
FROM MasterTable MT 
INNER JOIN SubTableA STA ON MT.MasterId = STA.MasterId

MT и STA являются псевдонимами, поэтому нам не нужно вводить полные имена таблиц, когда мы выясняем, какой из двух главных идентификаторов мыОбращаемся к.

Если бы мы тогда хотели только значения для одного, конкретного основного идентификатора, мы могли бы добавить это как предложение where в конце:

SELECT *
FROM MasterTable MT 
INNER JOIN SubTableA STA ON MT.MasterId = STA.MasterId
WHERE MT.MasterId = ?

Если нам нужны столбцыиз дополнительных таблиц мы могли бы также присоединиться к этим таблицам:

SELECT *
FROM MasterTable MT 
INNER JOIN SubTableA STA ON MT.MasterId = STA.MasterId
INNER JOIN SubTableB STB ON MT.MasterId = STB.MasterId
WHERE MT.MasterId = ?

Мы указываем INNER JOIN, потому что мы хотим, чтобы записи возвращались только там, где есть совпадающие значения во всех трех таблицах.Если бы SubTableB имел значения только для каждого мастер-идентификатора в течение некоторого времени, то мы бы хотели переключиться на LEFT JOIN или LEFT OUTER JOIN, который велел бы базе данных возвращать наши столбцы со стороны LEFT соединения, даже если нетсоответствующие столбцы доступны на правой стороне.

Таким образом, чтобы получить все столбцы в ситуации, когда у нас не всегда могут быть записи SubTableB, но все еще нужны столбцы Master и SubTableA:

SELECT *
FROM MasterTable MT 
INNER JOIN SubTableA STA ON MT.MasterId = STA.MasterId
LEFT JOIN SubTableB STB ON MT.MasterId = STB.MasterId
WHERE MT.MasterId = ?

, если этоВозможно, что у вас будет несколько записей в одной из SubTables для одного MasterId, тогда будут возвращены строки с каждой возможной комбинацией строк таблицы, которые соответствуют критериям JOIN.

Итак, если бы у нас была одна запись в MasterTable с идентификатором 5, 1 в SubTableA с мастер-идентификатором 5 и 3 в SubTableB с идентификатором 5, то мы фактически получили бы 3 строки назад,1 для каждой комбинации значений MasterTable и SubTableA со значениями SubTable3.Таким образом, на стороне клиента вам нужно будет иметь возможность обрабатывать повторяющиеся значения / строки или разделить запрос для отдельного выполнения запроса из SubTableB.

VBScript SQL Code

КодВы предоставили, в то время как образец, имеет два недостатка.Во-первых, поскольку вы объединяете аргумент в строку базы данных, специальные символы в этой строке могут нарушить вашу инструкцию SQL или, если вы извлекаете это значение из формы POST, Querystring и т. Д., Конечный пользователь может фактически вставить инструкцию SQLв переменную для запуска в вашей базе данных (потенциально отбрасывая ценные записи, манипулируя базой данных или даже даже загружая трояны или исполняемые файлы на сервер, в зависимости от уровня разрешений).Вторым недостатком является то, что есть потенциальные недостатки выполнения такой строки.В зависимости от вашего механизма базы данных вы можете получить незначительные потери производительности из-за неявных преобразований типов, отсутствия планового кэширования и т. Д. Просто потому, что оператор был доставлен в виде непараметризованной строки.

Чтобы решить эти проблемы, вы должны изучитьиспользование параметризованных операторов SQL или создание хранимой процедуры для вашего оператора и вызов ее с параметризованными значениями.объект ADODB имеет поддержку параметров:

Dim yourKeyValue : yourKeyValue = 5

Dim objConn, objCommand, rsResults
Set objConn = Server.CreateObject("ADODB.Connection")
objConn.Open("Your connection string")

Set objCommand = Server.CreateObject("ADODB.Command")

objCommand.ActiveConnection = objConn
objCommand.CommandText = "YourStoreProcName"
objCommand.CommandType = 4   'stored proc type/enum

objCommand.Parameters.Append objCommand.CreateParameter("Key", 3,1,,yourKeyValue)          
set rsResults = objCommand.Execute()

Дополнительная информация о параметрах и константах: http://www.w3schools.com/ado/met_comm_createparameter.asp

Дополнительная информация о CommandType: http://www.w3schools.com/ado/prop_comm_commandtype.asp

Вы можете изменитьвыведите текст команды для строки SQL вместо хранимой процедуры и используйте? -marks в качестве заполнителей для определяемых вами параметров.

Дополнительная очистка

Еще немного быстрой очистки.

Вместо того, чтобы указывать * для вашего запроса, вы, вероятно, захотите указать список столбцов, которые вы на самом деле хотите вернуть.Это сократит объем данных, поступающих по сети, до того, что вам нужно, точно скажет базе данных, что вам нужно, чтобы не пришлось предварительно искать имена полей самостоятельно, и это уменьшит некоторую путаницу в ваших данных.объект набора записей (в противном случае, например, у вас было бы довольно много основных столбцов идентификатора).

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

0 голосов
/ 08 декабря 2011

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

...