Вызов процедуры sql: Вызов хранимой процедуры — SQL Server

Вызов хранимой процедуры — SQL Server


  • Статья



Применимо к: SQL Server Azure SQL DatabaseУправляемый экземпляр SQL AzureAzure Synapse AnalyticsAnalytics Platform System (PDW)

Драйвер SQL SERVER NATIVE CLIENT ODBC поддерживает escape-последовательность ODBC CALL и инструкцию Transact-SQLEXECUTE для выполнения хранимых процедур. Escape-последовательность ODBC CALL является предпочтительным методом. Использование синтаксиса ODBC позволяет приложению получать коды возврата хранимых процедур, а драйвер ODBC SQL Server Native Client также оптимизирован для использования протокола, изначально разработанного для отправки вызовов удаленных процедур (RPC) между компьютерами, на которых выполняется SQL Server. Этот протокол RPC повышает производительность, устраняя большую часть обработки параметров и синтаксической проверки инструкций на сервере.

Примечание

При вызове SQL Server хранимых процедур с помощью именованных параметров с ODBC (дополнительные сведения см. в разделе Привязка параметров по имени (именованные параметры)) имена параметров должны начинаться с символа @. Это ограничение, характерное для SQL Server. Драйвер ODBC SQL Server Native Client применяет это ограничение более строго, чем компоненты доступа к данным Майкрософт (MDAC).

Управляющая последовательность ODBC CALL для вызова процедуры такова:

{[?=]callprocedure_name[([parameter][,[parameter]]…)]}

где procedure_name задает имя процедуры, а параметр — параметр процедуры. Именованные параметры поддерживаются только в инструкциях, использующих escape-последовательности ODBC CALL.

Процедура может иметь параметры или не иметь их. Она также может возвращать значение (на что указывает необязательный маркер параметра «?=» в начале синтаксической конструкции). Если параметр является входным или входным-выходным, то может представлять собой литерал или маркер параметра. Если параметр является выходным, то должен быть маркером параметра, поскольку выходной параметр неизвестен. Маркеры параметров должны быть привязаны к SQLBindParameter перед выполнением инструкции вызова процедуры.

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

{callprocedure_name( )}

Если процедура не имеет ни одного параметра, ее вызов завершается ошибкой. Если процедура вызывается без скобок, драйвер не передает какие-либо значения параметров. Пример:

{callprocedure_name}

В вызовах процедур можно задавать литералы для входных или входных-выходных параметров. Например, процедура InsertOrder имеет пять входных параметров. В следующем вызове процедуры InsertOrder пропущен первый параметр, указан литерал для второго параметра и используется маркер параметра для третьего, четвертого и пятого параметра. (Параметры нумеруются последовательно, начиная с 1.)

{call InsertOrder(, 10, ?, ?, ?)}  

Обратите внимание, что даже если параметр пропущен, запятая, отделяющая его от других параметров, должна присутствовать. Если пропущен входной или входной-выходной параметр, процедура использует значение по умолчанию. Другие способы задать значение по умолчанию для входного или входного-выходного параметра таковы: присвоить значение буфера длины и индикатора, привязанное к параметру процедуры SQL_DEFAULT_PARAM, или использовать ключевое слово DEFAULT.

Если входной-выходной параметр пропущен или в качестве параметра выступает литерал, то драйвер отбрасывает выходное значение. Аналогичным образом, если пропущен маркер параметра для значения, возвращаемого процедурой, драйвер отбрасывает возвращаемое значение. Наконец, если в приложении задан параметр возвращаемого значения для процедуры, которая не возвращает значение, драйвер задает значение буфера длины и индикатора, привязанное к параметру процедуры SQL_NULL_DATA.

Драйвер ODBC SQL Server Native Client по умолчанию также поддерживает параметр совместимости, характерный для escape-последовательности ODBC {CALL }. Он принимает инструкции CALL только с одним набором двойных кавычек, ограничивающих все имя хранимой процедуры:

{ CALL "master.dbo.sp_who" }  

По умолчанию драйвер ODBC SQL Server Native Client также принимает инструкции CALL, которые соответствуют правилам ISO, и заключают каждый идентификатор в двойные кавычки:

{ CALL "master"."dbo"."sp_who" }  

Однако при выполнении с параметрами по умолчанию драйвер ODBC SQL Server Native Client не поддерживает использование любой из форм идентификаторов в кавычках с идентификаторами, содержащими символы, не указанные в качестве допустимых в идентификаторах стандарта ISO. Например, драйвер не может получить доступ к хранимой процедуре с именем My.Proc с помощью инструкции CALL с идентификаторами в кавычках:

{ CALL "MyDB"."MyOwner"."My.Proc" }  

Эта инструкция интерпретируется драйвером следующим образом:

{ CALL MyDB.MyOwner.My.Proc }  

Сервер выдает ошибку о том, что связанный сервер с именем MyDB не существует.

При использовании идентификаторов, заключенных в квадратные скобки, эта инструкция интерпретируется правильно:

{ CALL [MyDB].[MyOwner].[My.Table] }  

См. также:

Выполнение хранимых процедур

sql — Вызов хранимой процедуры из хранимой процедуры не даёт результатов


Вопрос задан


Изменён
4 года 2 месяца назад


Просмотрен
223 раза

Имеется две хранимые процедуры — p1 и p2. p1 возвращает данные из таблицы Table1 табличного типа table1_type с каким-то содержимым, а p2 просто возвращает то, что вернула p1

CREATE PROCEDURE dbo.p1
  @Resp INT OUTPUT
AS 
SET @Resp = 0;
SELECT * FROM Table1;
GO
CREATE PROCEDURE dbo.p2
  @Resp INT OUTPUT
AS 
DECLARE @tmp table1_type;
INSERT INTO @tmp EXEC dbo.p1 @Resp OUTPUT;
SELECT * FROM @tmp;
GO

Если сделать следующий запрос

DECLARE @tmp dbo.table1_type;
DECLARE @Resp INT;
INSERT INTO @tmp EXEC dbo.p1 @Resp OUTPUT;
SELECT * FROM @tmp;

то в таблице @tmp появится содержимое таблицы Table1 и переменная @Resp станет равна 0. Но если вызвать процедуру dbo.p2 то она ничего не вернёт (@tmp будет пустой) и переменная @Resp ничему не будет равна.

DECLARE @tmp dbo.table1_type;
DECLARE @Resp INT;
INSERT INTO @tmp EXEC dbo.p2 @Resp OUTPUT;
SELECT * FROM @tmp;

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

  • sql
  • sql-server






2

Проблема была в использовании конструкции INSERT INTO . .. EXEC ... во вложенной процедуре. Во вложенной процедуре эту конструкцию использовать нельзя. Поэтому, если обойти этот момент и возвращать данные, например, через OUTPUT параметры, то всё складывается хорошо. Ответ нашёл здесь http://www.t-sql.ru/post/An_INSERT_EXEC_statement_cannot_be_nested.aspx







Зарегистрируйтесь или войдите

Регистрация через Google

Регистрация через Facebook

Регистрация через почту

Отправить без регистрации

Почта

Необходима, но никому не показывается

Отправить без регистрации


Почта

Необходима, но никому не показывается




Нажимая на кнопку «Отправить ответ», вы соглашаетесь с нашими пользовательским соглашением, политикой конфиденциальности и политикой о куки


Вызов хранимой процедуры из другой хранимой процедуры SQL Server

Задавать вопрос

спросил

Изменено
3 года, 3 месяца назад

Просмотрено
203 тыс. раз

У меня есть 3 хранимые процедуры вставки, каждая SP вставляет данные в 2 разные таблицы

 Таблица 1 Таблица 2
idPerson
имя продуктаНазвание
номер телефона описание продукта
FK-idProduct
 

SP для таблицы 1 SP для таблицы 2

 создать процедуру test1 создать процедуру test2
С С
ВЫПОЛНИТЬ от имени вызывающего абонента ВЫПОЛНИТЬ от имени вызывающего абонента
КАК КАК
объявить объявить
@idPerson, @idProduct,
@name varchar(20), @productName varchar(50),
@phone varchar(20) @productoDescription varchar(50)
  УСТАНОВИТЬ nocount on; УСТАНОВИТЬ nocount on;
    Начать Начать
      вставить в таблицу1(вставить в таблицу2(
                idPerson, idProduct,
                имя продукта,
                телефон) описание товара)
          значения( значения(
                @idPerson, @idProduct,
                @имя, @названиепродукта,
                @телефон) @описание продукта)
      конец конец
 

Мне нужно вызвать хранимую процедуру test 2 из хранимой процедуры test 1 и вставить FK-ID в таблицу 1

Просто вызовите test2 из test1 , например:

 EXEC test2 @newId, @prod, @desc;
 

Обязательно получите @id с помощью SCOPE_IDENTITY(), которая получает последнее значение идентификатора, вставленное в столбец идентификаторов в той же области:

 ВЫБЕРИТЕ @newId = SCOPE_IDENTITY()
 

3

Вы можете добавить параметр OUTPUT в test2 и установить для него новый идентификатор сразу после INSERT, используя:

 SELECT @NewIdOutputParam = SCOPE_IDENTITY()
 

Затем в test1 извлеките его следующим образом:

 DECLARE @NewId INTEGER
ВЫПОЛНИТЬ test2 @NewId ВЫВОД
-- Теперь используйте @NewId по мере необходимости
 

2

Прежде всего, если table2 idProduct является идентификатором, вы не можете вставить его явно, пока не установите IDENTITY_INSERT для этой таблицы

 SET IDENTITY_INSERT table2 ON;
 

перед вставкой.

Таким образом, одно из двух, вы изменяете свое второе хранилище и вызываете его только с параметрами productName и productDescription , а затем получаете новый идентификатор

 EXEC test2 'productName', 'productDescription'
УСТАНОВИТЬ @newID = SCOPE_IDENTIY()
 

или у вас уже есть идентификатор продукта, и вам не нужно вызывать SCOPE_IDENTITY() и вы можете сделать вставку в table1 с этим идентификатором

Зарегистрируйтесь или войдите в систему

Зарегистрируйтесь с помощью Google

Зарегистрироваться через Facebook

Зарегистрируйтесь, используя электронную почту и пароль

Опубликовать как гость

Электронная почта

Требуется, но никогда не отображается

Опубликовать как гость

Электронная почта

Требуется, но не отображается

sql server — вызов конкретной хранимой процедуры на основе параметра

У меня есть хранимые процедуры:

  1. [SP_Fetch_Budget_Data_ADF]
  2. SP_Fetch_Data_ADF

Обе эти хранимые процедуры имеют одинаковые параметры:

 CREATE PROCEDURE [DW]. [SP_Fetch_Budget_Data_ADF]
    @Дата varchar(10),
    @Entity varchar (12),
    @Сценарий varchar(10)
 

Параметры передаются из другого инструмента. Моя цель — написать третью хранимую процедуру, в которой я передаю параметр @Scenario varchar(10) (тот же параметр, что и для обеих хранимых процедур, как показано выше, поэтому предполагается, что этот параметр передается всем трем хранимым процедурам).

Если @Scenario = «фактический», выполните SP_Fetch_Data_ADF , иначе выполните SP_Fetch_Budget_Data_ADF .

Я нашел этот ответ, но не понял, как передать параметр.

ОБНОВЛЕНИЕ

Ниже мой код, но я получаю эту ошибку:

Не удалось найти хранимую процедуру «SP_Fetch_Budget_Data_ADF»

Код:

 СОЗДАТЬ ПРОЦЕДУРУ [DW].[SP_EXECUTE_ADF]
@Сценарий varchar(10)
КАК
НАЧИНАТЬ
УСТАНОВИТЬ БЕЗ СЧЕТА;

DECLARE @queryToRun NVARCHAR(128) = 'ВЫПОЛНИТЬ';
ВЫБЕРИТЕ @queryToRun = @queryToRun + CASE
КОГДА @Scenario = 'фактический'
ТОГДА 'DW.