Как передать значения параметров в запрос T-SQL

Я использую следующий запрос T-SQL в SQL Server 2005 (IDE Management Studio):

DECLARE @id int;
DECLARE @countVal int;
DECLARE @sql nvarchar(max);
SET @id = 1000;
SET @sql = 'SELECT COUNT(*) FROM owner.myTable WHERE id = @id';
EXEC (@sql) AT oracleServer -- oracleServer is a lined server to Oracle

Я не уверен, как передать входной параметр @id в запрос EXEC и передать результат подсчета в @countVal. Я видел несколько примеров для сервера Microsoft SQL, например:

EXEC (@sql, @id = @id)

Я пробовал это для Oracle, но получил сообщение об ошибке:

OLE DB provider "OraOLEDB.Oracle" for linked server "oracleServer" 
returned message "ORA-00936: missing expression"

Ответов (3)

Решение

Попробуй это:

EXEC sp_executesql @sql, N'@id int', @id

Больше информации в этой замечательной статье: http://www.sommarskog.se/dynamic_sql.html


Что касается вывода, ваш SELECT должен выглядеть примерно так:

SELECT @countVal = COUNT(id) FROM owner.myTable WHERE id = @id

Я выбираю id вместо *, чтобы не извлекать ненужные данные ...

Тогда ваш динамический sql должен быть примерно таким:

EXEC sp_executesql @sql, 
                   N'@id int, @countVal int OUTPUT', 
                   @id, 
                   @countVal OUTPUT

Этот пример адаптирован из той же статьи, указанной выше, в разделе sp_executesql .


Что касается вашей ошибки Oracle, вам нужно будет узнать точный SQL, который sp_executesql отправляет в Oracle. Если в Oracle есть профилировщик или журнал запросов, это может помочь. У меня ограниченный опыт работы с Oracle, но это будет следующим логическим шагом для устранения вашей проблемы.

Я не знаю, почему вы передаете идентификатор отдельно.

Вы могли бы сделать следующее
SET @sql = 'SELECT COUNT(*) FROM owner.myTable WHERE id = ' + @id

Быстрый и грязный способ - просто построить строку перед использованием оператора EXEC, однако это не рекомендуется, поскольку вы можете открыть себя для внедрения SQL.

DECLARE @id int;
DECLARE @countVal int;
DECLARE @sql nvarchar(max);
SET @id = 1000;
SET @sql = 'SELECT COUNT(*) FROM owner.myTable WHERE id = ' + @id 
EXEC (@sql) AT oracleServer -- oracleServer is a lined server to Oracle

Правильный способ сделать это - использовать системную хранимую процедуру sp_executesql, как подробно описано magnifico и рекомендовано Microsoft в электронной документации:

EXEC sp_executesql @sql, N'@id int', @id