Настоящее описание является результатом личных экспериментов и наблюдений автора и не претендует на полноту, точность и всеобъемлемость. ради доступности некоторые термины и выкладки даны в упрощенном виде. по возможности такие места снабжены ссылками на более подробное описание. 1. отличие описания методов в vbscript и javascript 2. как ограничить кол-во выводимых строк при выполнении запроса? 3. полезный трюк: как организовать вывод объектов (например, картинок) в таблице по их URL'ам 4. быть осторожным с RecordCount 5. кавычки 6. внимание: типы char и varchar 7. по поводу длины строки 8. лучше пользоваться свойством .value 9. "если RecordSet есть, то его сразу нет..." 1. Отличие описания методов в vbscript и javascript Во что я сразу же вляпался, когда задумал переводить asp-файлы из vbscript на javascript, это отличие синтаксического оформления методов в разных скрипт-языках. если в vbscript работала строка: rs.MoveNext то в javascript соответствующая строка rs.MoveNext; выдавала странную ошибку типа "объект не поддерживает данное свойство или метод". "с какой стати не поддерживает?" - достаточно долго спрашивал себя я, пока не догадался приписать пару скобок :): rs.MoveNext(); 2. Как ограничить кол-во выводимых строк при выполнении запроса? Засунуть результат запроса в массив нужного размера; выдать на экран содержимое массива. Пример: <% ' Открытие базы данных, формирование запроса. Set Conn = Server.CreateObject("ADODB.Connection") Conn.Open "ADOSamples" sql="SELECT * FROM Orders" Set RS = Conn.Execute(sql) %> <TABLE BORDER=1> <TR> <% For i = 0 to RS.Fields.Count - 1 ' вывод имен полей%> <TD><B><% = RS(i).Name %></B></TD> <% Next %> </TR> <% ' Поместить первые 100 строк запроса в 2-мерный variant-массив v=RS.GetRows(100) RS.close ' закрыть объект типа RecordSet Conn.close ' закрыть объект типа Connection %> 3. Полезный трюк: как организовать вывод объектов (например, картинок) в таблице по их URL'ам Обозвать соответствующим образом имя поля, содержащего URL, например URLimage. В процессе вывода данных проверять имя поля на наличие подстроки "URL" и в зависимости от этого выводить содержимое поля как текст или как ссылку, или как объект, на который эта ссылка указывает. Пример: <% ' Note: The following is a bit of a hack...If the column name contains ' the string "URL" anywhere in it, assume it is a URL to a gif or jpg ' file and generate the HTML to get the image and display. This works ' for the Products table in the Adventure Works database, but is not a ' general purpose solution. If InStr(RS(i).Name, "URL") > 0 Then Response.Write "<img src=""" & RS(i) & """>" Else Response.Write RS(i) End If %> 4. Быть осторожным с RecordCount Количество записей в полученном запросе можно определить с помощью property RecordCount: <% sql="SELECT * FROM Orders" Set RS = Conn.Execute(sql) RS.RecordCount %> Однако это значение может равняться -1 только из-за того, что ADO в используемой конфигурации не может определить количество строк. 5. Кавычки Eсли в запросе используются строковые значения, то лучше использовать ' (апостроф), а не " (двойной апостроф). Несмотря на то, что в ISQL/w выполняются оба запроса одинаково, в asp (быть может в этом виноват javascript) двойной апостроф вызывает ошибку. Например лучше так: <% sql="SELECT * FROM Orders WHERE id = '"+id+"'"; %> а не так: <% sql="SELECT * FROM Orders WHERE id = ""+id+"""; %> 6. Внимание: типы char и varchar Cравнивая значения переменной, полученной из заполненной формы, и извлеченной из поля таблицы типа char я не мог добиться, чтобы javascript посчитал их равными, хотя внешне они выглядели совершенно одинаковыми. Причем с остальными переменными было все нормально. Оказалось, что они сравнивались с полями типа varchar. Вспомнив почти забытые знания о типах полей субд oracle, я пришел к выводу, что виноват тип char, значение которого имеет длину такую, какую объявили для поля. Значение же типа varchar имеет длину в соответствии с содержащейся строкой. Промучившись с определением длины переменной, я решил, что лучше всего в таблицах не использовать тип char без особой необходимости. 7. По поводу длины строки Переменные, полученные из формы способом: name = Request.form("name"); или из базы данных: sql = "SELECT name, passw, email FROM persons WHERE email = '"+email+"'"; rs = conn.Execute(sql); name = rs(0); на вопрос name.length отвечают "неизвестно". Когда у меня все же возникла необходимость в определении длины таких значений, я поступил так: var name = ""; name += Request.form("name"); var name = ""; sql = "SELECT name, passw, email FROM persons WHERE email = '"+email+"'"; rs = conn.Execute(sql); name += rs(0); 8. Лучше пользоваться свойством .value Нужно быть осторожным с объектами Recordet. Если в html еще можно вывести переменную так: <% rs = conn.Execute(sql); %> <%= rs(0)%> то, работая с переменной, можно напороться на неприятности. Например, выражение (rs(0) == name) выдаст "ложь" при том, что при выводе оба значения будут одинаковыми. Правильнее сделать так: (rs(0).value == name) 9. "Если RecordSet есть, то его сразу нет..." Опять про осторожность с объектами Recordet. Допустим мы вызываем хранимую процедуру: CREATE PROCEDURE do_test1 @num int AS select * from test where num = @num return 100 При некоторых значениях параметра @num данная процедура будет выдавать одну или строчку из таблицы test, а при других - не выдавать ни одной. Если мы обратимся к rs, полученному, например, таким способом: rs = conn.Execute("do_test1 1"); rs.Close(); то, никаких неприятностей не возникнет. Если же процедура будет выглядеть таким образом: CREATE PROCEDURE do_test2 @num int AS if @num = 1 select * from test where num = @num return 100 else return 200 то операторы: rs = conn.Execute("do_test2 1"); rs.Close(); с рук сойдут, а вот: rs = conn.Execute("do_test2 0"); rs.Close(); вызовут ошибку на Close(): ADODB.Recordset error '800a0e78' Invalid operation on closed object. |