1. Отличие описания методов в vbscript и
javascript
Во что я сразу же вляпался, когда задумал переводить asp-файлы
из vbscript на javascript, это отличие синтаксического оформления методов в
разных скрипт-языках. если в vbscript работала строка:
то в javascript соответствующая строка
выдавала странную ошибку типа "объект не поддерживает данное
свойство или метод". "с какой стати не поддерживает?" - достаточно долго
спрашивал себя я, пока не догадался приписать пару скобок :):
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)%>
то, работая с переменной, можно напороться на неприятности.
Например, выражение
выдаст "ложь" при том, что при выводе оба значения будут
одинаковыми. Правильнее сделать так:
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.