Есть много статей об ASP и хранимых процедурах (Stored Treatments), но я сомневаюсь, что авторы действительно их практиковали. Когда я был новичком, я просмотрел много соответствующей информации и обнаружил, что многие из предложенных методов на практике не совпадают. Для простых приложений эти материалы могут быть полезны, но этим они и ограничиваются, поскольку по сути они одинаковы и копируют друг друга. Для чуть более сложных приложений все они неясны.
Теперь я в основном получаю доступ к SQL Server, вызывая хранимые процедуры. Хотя нельзя гарантировать абсолютную корректность следующего текста, я надеюсь, что он будет полезен всем.
Хранимая процедура — это одна или несколько команд SQL, хранящихся в базе данных в виде исполняемых объектов.
Определения всегда абстрактны. Хранимая процедура на самом деле представляет собой набор операторов SQL, которые могут выполнять определенные операции, но этот набор операторов размещается в базе данных (здесь мы говорим только о SQL Server). Если мы создаем хранимые процедуры и вызываем хранимые процедуры в ASP, мы можем избежать смешивания операторов SQL с кодом ASP. У этого есть как минимум три преимущества:
Во-первых, значительно повысить эффективность. Скорость выполнения самой хранимой процедуры очень высока, а вызов хранимой процедуры может значительно сократить количество взаимодействий с базой данных.
Во-вторых, повысить безопасность. Если вы смешиваете операторы SQL в коде ASP, то если код будет скомпрометирован, это также означает, что структура библиотеки будет скомпрометирована.
В-третьих, это способствует повторному использованию операторов SQL.
В ASP хранимые процедуры обычно вызываются через объект команды. В зависимости от ситуации в этой статье также представлены другие методы вызова. Для удобства объяснения сделаны следующие простые классификации в зависимости от ввода и вывода хранимого процесса:
1. Хранимая процедура, которая возвращает только один набор записей, предполагает следующую хранимую процедуру (цель этой статьи не состоит в описании синтаксиса T-SQL, поэтому хранимая процедура предоставляет только код без пояснений):
/*SP1*/
СОЗДАТЬ ПРОЦЕДУРУ dbo.getUserList
как
установить nocount на
начинать
выберите * из dbo.[userinfo]
конец
go
получает все записи в таблице userinfo и возвращает набор записей. Код ASP для вызова хранимой процедуры через объект команды выглядит следующим образом:
'**Вызов хранимой процедуры через объект команды**
DIM MyComm, MyRst
Установите MyComm = Server.CreateObject("ADODB.Command")
MyComm.ActiveConnection = MyConStr 'MyConStr — строка подключения к базе данных.
MyComm.CommandText = "getUserList" 'Укажите имя хранимой процедуры
MyComm.CommandType = 4 'Указывает, что это хранимая процедура.
MyComm.Prepared = true 'Требуется сначала скомпилировать команды SQL
Установите MyRst = MyComm.Execute
Set MyComm = Nothing
Набор записей, полученный хранимой процедурой, назначается MyRst. Далее можно работать с MyRst.
В приведенном выше коде атрибут CommandType указывает тип запроса. Значение и описание следующие:
-1 указывает, что тип параметра CommandText не может быть определен.
1 указывает, что CommandText — это общий тип команды.
2 указывает, что параметр CommandText является именем существующей таблицы.
4 Указывает, что параметр CommandText является именем хранимой процедуры
. Хранимая процедура также может быть вызвана через объект Connection или объект Recordset. Существуют следующие методы:
'**Вызовите хранимую процедуру через объект Connection**.
DIM MyConn, MyRst
Установите MyConn = Server.CreateObject("ADODB.Connection")
MyConn.open MyConStr 'MyConStr — строка подключения к базе данных.
Set MyRst = MyConn.Execute("getUserList",0,4) 'Последний параметр имеет то же значение, что и CommandType
Set MyConn = Nothing
'**Вызов хранимой процедуры через объект Recordset**
DIM MyRst
Установите MyRst = Server.CreateObject("ADODB.Recordset")
MyRst.open "getUserList", MyConStr,0,1,4
'MyConStr — это строка подключения к базе данных, последний параметр имеет то же значение, что и CommandType.
2. Для хранимых процедур без ввода и вывода см. следующие хранимые процедуры:
/*SP2*/
СОЗДАТЬ ПРОЦЕДУРУ dbo.delUserAll
как
установить nocount на
начинать
удалить из dbo.[userinfo]
конец
go
удаляет все записи в таблице userinfo без какого-либо ввода или вывода. Метод вызова в основном такой же, как указано выше, за исключением того, что нет необходимости получать набор записей:
'**Вызовите хранимую процедуру с помощью команды. объект**
ДИМ MyComm
Установите MyComm = Server.CreateObject("ADODB.Command")
MyComm.ActiveConnection = MyConStr 'MyConStr — строка подключения к базе данных.
MyComm.CommandText = "delUserAll" 'Укажите имя хранимой процедуры
MyComm.CommandType = 4 'Указывает, что это хранимая процедура.
MyComm.Prepared = true 'Требуется сначала скомпилировать команды SQL
MyComm.Execute 'Нет необходимости получать набор записей здесь
Set MyComm = Nothing
Конечно, такие хранимые процедуры также можно вызывать через объект Connection или объект Recordset, но объект Recordset создается для получения набора записей. Если набор записей не возвращается, лучше использовать объект Command.
3. При выполнении операций, аналогичных SP2, хранимые процедуры с возвращаемыми значениями должны в полной мере использовать мощные возможности обработки транзакций SQL Server для обеспечения согласованности данных. Более того, нам может понадобиться хранимая процедура для возврата статуса выполнения. Для этого измените SP2 следующим образом:
/*SP3*/.
СОЗДАТЬ ПРОЦЕДУРУ dbo.delUserAll
как
установить nocount на
начинать
НАЧАТЬ ТРАНЗАКЦИЮ
удалить из dbo.[userinfo]
ЕСЛИ @@error=0
начинать
СОВЕРШИТЬ ТРАНЗАКЦИЮ
вернуть 1
конец
ЕЩЕ
начинать
ОТКАТ ТРАНЗАКЦИИ
вернуть 0
конец
возвращаться
конец
go
возвращает 1, если удаление выполнено успешно, в противном случае она возвращает 0 и выполняет операцию отката. Чтобы получить возвращаемое значение в ASP, вам необходимо использовать коллекцию параметров для объявления параметров:
'**Вызовите хранимую процедуру с возвращаемым значением и получите возвращаемое значение**
DIM MyComm, MyPara
Установите MyComm = Server.CreateObject("ADODB.Command")
MyComm.ActiveConnection = MyConStr 'MyConStr — строка подключения к базе данных.
MyComm.CommandText = "delUserAll" 'Укажите имя хранимой процедуры
MyComm.CommandType = 4 'Указывает, что это хранимая процедура.
MyComm.Prepared = true 'Требуется сначала скомпилировать команды SQL
'Объявляем возвращаемое значение
Установить Mypara = MyComm.CreateParameter("RETURN",2,4)
MyComm.Parameters.Append MyPara
MyComm.Execute
'Получаем возвращаемое значение
DIM retValue
retValue = MyComm(0) 'или retValue = MyComm.Parameters(0)
Установите MyComm = Nothing.
В MyComm.CreateParameter("RETURN",2,4) значение каждого параметра следующее:
Первый параметр («RETURE») — это имя параметра. Имя параметра можно задать произвольно, но обычно оно должно совпадать с именем параметра, объявленным в хранимой процедуре. Вот возвращаемое значение, я обычно устанавливаю его как «RETURE»;
Второй параметр (2) указывает тип данных параметра. Коды конкретных типов приведены в справочнике ADO. Ниже приведены общие коды типов.
адБигИнт: 20;
адБинари: 128;
adBoolean: 11;
адчар: 129;
adDBTimeStamp: 135;
адЕмпти: 0;
адИнтегер: 3;
adSmallInt: 2;
адТиниИнт: 16;
adVarChar: 200;
В качестве возвращаемого значения можно брать только целочисленные значения, а от -1 до -99 — зарезервированные значения;
Третий параметр (4) указывает тип параметра, где 4 указывает, что это возвращаемое значение. Описание значения этого параметра следующее:
0: тип не может быть определен; 1: входные параметры; 2: входные параметры; 3: входные или выходные параметры; 4: возвращаемое значение.
Приведенный выше код ASP следует считать полным кодом, то есть наиболее сложным кодом. Фактически,
Set Mypara = MyComm.CreateParameter("RETURN",2,4)
MyComm.Parameters.Append MyPara
можно упростить до
MyComm.Parameters.Append MyComm.CreateParameter("RETURN",2,4)
и даже продолжать упрощать, что будет объяснено позже.
Для хранимых процедур с параметрами их можно вызвать только с помощью объекта Command (есть также информация, что их можно вызвать через объект Connection или объект Recordset, но я не пробовал).
4. Возвращаемое значение хранимой процедуры с входными и выходными параметрами на самом деле является специальным входным параметром. В большинстве случаев мы используем хранимые процедуры, которые имеют как входные, так и выходные параметры. Например, мы хотим получить имя пользователя с определенным идентификатором в таблице информации о пользователе. В этот момент есть входной параметр. --user ID и выходной параметр ----имя пользователя. Хранимая процедура для реализации этой функции выглядит следующим образом:
/*SP4*/
СОЗДАТЬ ПРОЦЕДУРУ dbo.getUserName
@UserID целое число,
Вывод @UserName varchar(40)
как
установить nocount на
начинать
если @UserID имеет значение null, возврат
выберите @UserName=имя пользователя
из dbo.[информация пользователя]
где userid=@UserID
возвращаться
конец
перехода
к вызову хранимой процедуры выглядит следующим образом:
'**Вызов хранимой процедуры с входными и выходными параметрами**
DIM MyComm,ID пользователя,имя пользователя
ИД пользователя = 1
Установите MyComm = Server.CreateObject("ADODB.Command")
MyComm.ActiveConnection = MyConStr 'MyConStr — строка подключения к базе данных.
MyComm.CommandText = "getUserName" 'Укажите имя хранимой процедуры
MyComm.CommandType = 4 'Указывает, что это хранимая процедура.
MyComm.Prepared = true 'Требуется сначала скомпилировать команды SQL
'Объявляем параметры
MyComm.Parameters.append MyComm.CreateParameter("@UserID",3,1,4,UserID)
MyComm.Parameters.append MyComm.CreateParameter("@UserName",200,2,40)
MyComm.Execute
'Получаем параметры
Имя пользователя = МойКомм(1)
Set MyComm = Nothing
В приведенном выше коде вы можете видеть, что в отличие от объявления возвращаемого значения, при объявлении входных параметров требуется 5 параметров, а при объявлении выходных параметров — 4 параметра. При объявлении входных параметров пятью параметрами являются: имя параметра, тип данных параметра, тип параметра, длина данных и значение параметра. При объявлении входных параметров нет последнего параметра: значения параметра.
Особое внимание следует обратить на то: при объявлении параметров порядок должен быть таким же, как определенный в хранимой процедуре, а тип данных и длина каждого параметра также должны быть такими же, как определенные в хранимой процедуре.
Если хранимая процедура имеет несколько параметров, код ASP будет выглядеть громоздким. Для упрощения кода можно использовать команду with:
'**Вызов хранимой процедуры с входными и выходными параметрами (упрощенный код)**.
DIM MyComm,ID пользователя,имя пользователя
ИД пользователя = 1
Установите MyComm = Server.CreateObject("ADODB.Command")
с MyComm
.ActiveConnection = MyConStr 'MyConStr — это строка подключения к базе данных
.CommandText = "getUserName" 'Укажите имя хранимой процедуры
.CommandType = 4 'Указывает, что это хранимая процедура
.Prepared = true 'Требуется сначала скомпилировать команды SQL
.Parameters.append .CreateParameter("@UserID",3,1,4,UserID)
.Parameters.append .CreateParameter("@UserName",200,2,40)
.Выполнять
закончиться
Имя пользователя = МойКомм(1)
Set MyComm = Nothing
Если мы хотим получить имена 10 пользователей с идентификаторами от 1 до 10, нужно ли нам создавать объект Command 10 раз? Нет, если вам нужно вызвать одну и ту же хранимую процедуру несколько раз, вам нужно всего лишь изменить входные параметры, и вы получите разные входные параметры:
'**Вызов одной и той же хранимой процедуры несколько раз**
DIM MyComm,ID пользователя,имя пользователя
Имя пользователя = ""
Установите MyComm = Server.CreateObject("ADODB.Command")
для UserID = от 1 до 10
сMyComm
.ActiveConnection = MyConStr 'MyConStr — строка подключения к базе данных.
.CommandText = "getUserName" 'Укажите имя хранимой процедуры
.CommandType = 4 'Указывает, что это хранимая процедура
.Prepared = true 'Требуется сначала скомпилировать команды SQL
если UserID = 1, то
.Parameters.append .CreateParameter("@UserID",3,1,4,UserID)
.Parameters.append .CreateParameter("@UserName",200,2,40)
.Выполнять
еще
'Переназначаем значения входным параметрам (входные параметры и выходные параметры, значения параметров которых в этот момент не изменяются, не нужно переобъявлять)
.Parameters("@UserID") = UserID
.Выполнять
конец, если
закончиться
Имя пользователя = Имя пользователя + MyComm(1) + "," 'Возможно, вам нравится использовать массив хранения данных.
следующий
Set MyComm = Nothing
Как видно из приведенного выше кода: при повторном вызове одной и той же хранимой процедуры необходимо переназначить только те входные параметры, значения которых изменились. Этот метод имеет несколько входных и выходных параметров, и вызывается только один. каждый раз объем кода может быть значительно уменьшен при изменении значения входного параметра.
5. Хранимые процедуры, которые одновременно имеют возвращаемые значения, входные и выходные параметры. Как упоминалось ранее, при вызове хранимой процедуры порядок объявления параметров должен быть таким же, как порядок, определенный в хранимой процедуре. . Еще один момент, на который следует обратить особое внимание: если хранимая процедура имеет как возвращаемое значение, так и входные и выходные параметры, то возвращаемое значение должно быть объявлено первым.
Чтобы продемонстрировать вызывающий метод в этом случае, давайте улучшим приведенный выше пример. По-прежнему получаем имя пользователя с идентификатором 1, но возможно, что пользователь не существует (пользователь удален, а userid — самоувеличяющееся поле). Хранимая процедура возвращает разные значения в зависимости от того, существует пользователь или нет. На данный момент хранимая процедура и код ASP следующие:
/*SP5*/
СОЗДАТЬ ПРОЦЕДУРУ dbo.getUserName
--Чтобы усилить впечатление «порядка», измените порядок определения следующих двух параметров.
Вывод @UserName varchar(40),
@UserID целое число
как
установить nocount на
начинать
если @UserID имеет значение null, возврат
выберите @UserName=имя пользователя
из dbo.[информация пользователя]
где userid=@UserID
если @@rowcount>0
вернуть 1
еще
вернуть 0
возвращаться
конец
go
'**Вызов хранимой процедуры с возвращаемым значением, входными и выходными параметрами**
DIM MyComm,ID пользователя,имя пользователя
ИД пользователя = 1
Установите MyComm = Server.CreateObject("ADODB.Command")
сMyComm
.ActiveConnection = MyConStr 'MyConStr — строка подключения к базе данных.
.CommandText = "getUserName" 'Укажите имя хранимой процедуры
.CommandType = 4 'Указывает, что это хранимая процедура
.Prepared = true 'Требуется сначала скомпилировать команды SQL
' Сначала должно быть объявлено возвращаемое значение
.Parameters.Append .CreateParameter("RETURN",2,4)
'Порядок объявления следующих двух параметров также соответственно меняется на обратный.
.Parameters.append .CreateParameter("@UserName",200,2,40)
.Parameters.append .CreateParameter("@UserID",3,1,4,UserID)
.Выполнять
закончиться
если MyComm(0) = 1, то
Имя пользователя = МойКомм(1)
еще
Имя пользователя = «Этот пользователь не существует»
конец, если
Set MyComm = Nothing
6. Хранимые процедуры, которые одновременно возвращают параметры и наборы записей. Иногда нам нужны хранимые процедуры для одновременного возврата параметров и наборов записей. Например, при использовании хранимых процедур для разбиения по страницам нам необходимо возвращать такие параметры. как наборы записей и общие данные одновременно. Ниже приведена хранимая процедура для разбиения по страницам:
/*SP6*/.
СОЗДАТЬ ПРОЦЕДУРУ dbo.getUserList
@iPageCount int OUTPUT, --Общее количество страниц
@iPage int, --Номер текущей страницы
@iPageSize int --Количество записей на странице
как
установить nocount на
начинать
--Создать временную таблицу
создать таблицу #t (ID int IDENTITY, поле --auto-increment
идентификатор пользователя целое число,
имя пользователя varchar(40))
--Записать данные во временную таблицу
вставить в #t
выберите идентификатор пользователя, имя пользователя из dbo.[UserInfo]
упорядочить по идентификатору пользователя
— получить общее количество записей
объявить @iRecordCount int
set @iRecordCount = @@rowcount
--определить общее количество страниц
ЕСЛИ @iRecordCount%@iPageSize=0
SET @iPageCount=ПОТОЛОК(@iRecordCount/@iPageSize)
ЕЩЕ
SET @iPageCount=CEILING(@iRecordCount/@iPageSize)+1
--Если номер запрошенной страницы превышает общее количество страниц, будет отображена последняя страница.
ЕСЛИ @iPage > @iPageCount
SELECT @iPage = @iPageCount
— определить начало и конец текущей страницы
DECLARE @iStart int --начать запись
DECLARE @iEnd int --end запись
ВЫБЕРИТЕ @iStart = (@iPage - 1) * @iPageSize
SELECT @iEnd = @iStart + @iPageSize + 1
— получить текущую запись страницы.
выберите * из #t, где ID>@iStart и ID<@iEnd
--Удалить временную таблицу
DROP TABLE #t
— возвращает общее количество записей.
вернуть @iRecordCount
конец
В приведенной выше хранимой процедуре
go
вводит номер текущей страницы и количество записей на странице и возвращает набор записей текущей страницы, общее количество страниц и общее количество записей.Чтобы быть более типичным, общее количество записей возвращается в качестве возвращаемого значения. Ниже приведен код ASP, вызывающий хранимую процедуру (конкретная операция подкачки опущена):
'**Вызов хранимой процедуры подкачки**
Страница DIM сейчас, размер страницы, количество страниц, количество записей
DIM MyComm, MyRst
pagenow = Запрос («ПН»)
'Пользовательская функция, используемая для проверки натуральных чисел
если CheckNar(pagenow) = false, то pagenow = 1
размер страницы = 20
Установите MyComm = Server.CreateObject("ADODB.Command")
с помощью MyComm
.ActiveConnection = MyConStr 'MyConStr — строка подключения к базе данных.
.CommandText = "getUserList" 'Укажите имя хранимой процедуры
.CommandType = 4 'Указывает, что это хранимая процедура
.Prepared = true 'Требуется сначала скомпилировать команды SQL
'Возвращаемое значение (общее количество записей)
.Parameters.Append .CreateParameter("RETURN",2,4)
'Выходные параметры (общее количество страниц)
.Parameters.Append .CreateParameter("@iPageCount",3,2)
'Входные параметры (номер текущей страницы)
.Parameters.append .CreateParameter("@iPage",3,1,4,pagenow)
'Входные параметры (количество записей на странице)
.Parameters.append .CreateParameter("@iPageSize",3,1,4,pagesize)
SetMyRst = .Выполнить
закончиться
если MyRst.state = 0, то 'Данные не получены, MyRst закрыт
количество записей = -1
еще
MyRst.close 'Примечание. Чтобы получить значения параметров, необходимо сначала закрыть объект набора записей.
количество записей = MyComm(0)
количество страниц = MyComm(1)
если cint(pagenow)>=cint(pagecount), то pagenow=pagecount
конец, если
Set MyComm = Nothing
'Показать записи ниже
если количество записей = 0, то
Ответ. Напишите «Нет записи».
иначе, если количество записей > 0, тогда
MyRst.open
делать до MyRst.EOF
...
петля
'Следующее отображает информацию о пейджинге
...
еще 'recordcount=-1
Ответ. Напишите «Ошибка параметра».
end if
Что касается приведенного выше кода, то есть только один момент, который необходимо пояснить: при одновременном возврате набора записей и параметров, если вы хотите получить параметры, вам необходимо сначала закрыть набор записей, а затем открыть его, когда используя набор записей.
7. Хранимые процедуры, возвращающие несколько наборов записей. Первое, что рассказывается в этой статье, — это хранимые процедуры, возвращающие наборы записей. Иногда для возврата нескольких наборов записей требуется хранимая процедура. Как в ASP получить эти наборы записей одновременно? Чтобы проиллюстрировать эту проблему, добавьте в таблицу userinfo два поля: usertel и usermail и установите, чтобы только вошедшие в систему пользователи могли просматривать эти два содержимого.
/*СП7*/
СОЗДАТЬ ПРОЦЕДУРУ dbo.getUserInfo
@userid int,
@checklogin бит
как
установить nocount на
начинать
если @userid имеет значение null или @checklogin имеет значение null, возврат
выберите имя пользователя
из dbo.[usrinfo]
где userid=@userid
--Если вы вошли в систему, возьмите usertel и usermail.
если @checklogin=1
выберите usertel,usermail
из dbo.[информация пользователя]
где userid=@userid
возвращаться
конец
Ниже приведен
код ASP:
«**Вызов хранимой процедуры, возвращающей несколько наборов записей**.
DIM checklg, UserID, имя пользователя, UserTel, UserMail
DIM MyComm, MyRst
ИД пользователя = 1
'checklogin() — это пользовательская функция, определяющая, вошел ли посетитель в систему.
checklg = проверка входа()
Установите MyComm = Server.CreateObject("ADODB.Command")
с MyComm
.ActiveConnection = MyConStr 'MyConStr — это строка подключения к базе данных
.CommandText = "getUserList" 'Укажите имя хранимой процедуры
.CommandType = 4 'Указывает, что это хранимая процедура
.Prepared = true 'Требуется сначала скомпилировать команды SQL
.Parameters.append .CreateParameter("@userid",3,1,4,UserID)
.Parameters.append .CreateParameter("@checklogin",11,1,1,checklg)
SetMyRst = .Выполнить
закончиться
Set MyComm = Nothing
'Получить значение из первого набора записей
Имя пользователя = МойRst(0)
'Получаем значение из второго набора записей
если не MyRst, то ничего
Установите MyRst = MyRst.NextRecordset()
ПользовательТел = МойРст(0)
Пользовательская почта = МойRst(1)
конец, если
Set MyRst = Nothing
В приведенном выше коде метод NextRecordset объекта Recordset используется для получения нескольких наборов записей, возвращаемых хранимой процедурой.
До сих пор в этой статье давалось относительно полное объяснение различных ситуаций, в которых ASP вызывает хранимые процедуры. Наконец, давайте поговорим о различных методах вызова нескольких хранимых процедур в программе ASP.
В программе ASP возможно использовать как минимум следующие три метода для вызова нескольких хранимых процедур:
1. Создайте несколько объектов Command.
ДИМ MyComm
Установите MyComm = Server.CreateObject("ADODB.Command")
'Вызов хранимой процедуры номер один
...
Установить MyComm = Ничего
Установите MyComm = Server.CreateObject("ADODB.Command")
'Вызов хранимой процедуры номер два
...
Установить MyComm = Ничего
......
2. Создавать только объект Command, а при завершении вызова очищать его параметр
DIM MyComm
Установите MyComm = Server.CreateObject("ADODB.Command")
'Вызов хранимой процедуры номер один
.....
'Очистить параметры (при условии, что есть три параметра)
MyComm.Parameters.delete 2
MyComm.Parameters.delete 1
MyComm.Parameters.delete 0
'Вызов второй хранимой процедуры и очистка параметров
...
Set MyComm = Nothing
. На этот раз обратите внимание: порядок очистки параметров противоположен порядку объявления параметров. Причина не знаю.
3. Используйте метод Refresh коллекции данных «Параметры», чтобы сбросить объект «Параметры»
DIM MyComm.
Установите MyComm = Server.CreateObject("ADODB.Command")
'Вызов хранимой процедуры номер один
.....
'Сброс всех объектов параметров, содержащихся в коллекции данных параметров.
MyComm.Параметры.Обновить
'Вызов хранимой процедуры номер два
.....
Set MyComm = Nothing
Обычно считается, что повторное создание объектов — менее эффективный метод, но после тестирования (инструмент тестирования — Microsoft Application Center Test) результаты оказались неожиданными:
Метод 2 >= Метод 1 >> Метод 3
Скорость работы метода 2 больше или равна методу 1 (примерно на 4 %). Скорость работы этих двух методов намного выше, чем метода 3 (до 130 %). метод 1, если параметров много. Если нет, используйте метод 2.
Мне потребовался день, чтобы наконец описать свой поверхностный опыт вызова хранимых процедур в ASP. Среди них у некоторых я знаю только следствия, но не причины, а некоторые могут быть неправильными, но все они получены на основе моей личной практики. Пожалуйста, отнеситесь к этому критически, читатели. Если у вас есть другое мнение, пожалуйста, дайте мне знать. Заранее спасибо.