Как получить количество строк из EXEC () в TSQL SPROC? - PullRequest
18 голосов
/ 01 июня 2011

У меня есть sproc TSQL, который создает запрос и выполняет его следующим образом:

EXEC (@sqlTop + @sqlBody + @sqlBottom)

@ sqlTop содержит что-то вроде SELECT TOP (x) col1, col2, col3 ...

TOP (x) ограничит количество возвращаемых строк, поэтому позже я хочу узнать, какое именно число строк в таблице соответствует запросу.

Затем я заменяю @sqlTop на что-то вроде:

EXEC ('SELECT @ActualNumberOfResults = COUNT(*) ' + @sqlBody)

Я могу понять, почему это не работает, и почему возникает ошибка, не объявляющая значение, но я думаю, что она адекватно описывает то, что я пытаюсь достичь.

Есть идеи?

Ответы [ 6 ]

16 голосов
/ 01 июня 2011

Вместо этого динамический запрос может вернуть результат в виде набора строк, который затем будет вставлен в переменную таблицы (может быть также временной или обычной таблицей) с использованием синтаксиса INSERT ... EXEC. После этого вы можете просто прочитать сохраненное значение в переменную, используя SELECT @var = ...:

DECLARE @rowcount TABLE (Value int);
INSERT INTO @rowcount
EXEC('SELECT COUNT(*) ' + @sqlBody);
SELECT @ActualNumberOfResults = Value FROM @rowcount;
13 голосов
/ 06 января 2014

Поздно днем, но я нашел этот метод намного проще:

-- test setup
DECLARE @sqlBody nvarchar(max) = N'SELECT MyField FROM dbo.MyTable WHERE MyOtherField = ''x''';
DECLARE @ActualNumberOfResults int;

-- the goods
EXEC sp_executesql @sqlBody;
SET @ActualNumberOfResults = @@ROWCOUNT;
SELECT @ActualNumberOfResults;
12 голосов
/ 01 июня 2011

используйте sp_executesql и output parameter

пример

DECLARE @sqlBody VARCHAR(500),@TableCount INT, @SQL NVARCHAR(1000)

SELECT @sqlBody = 'from sysobjects'
SELECT @SQL = N'SELECT @TableCount = COUNT(*) ' + @sqlBody

EXEC sp_executesql @SQL, N'@TableCount INT OUTPUT', @TableCount OUTPUT

SELECT @TableCount
GO
2 голосов
/ 21 апреля 2015

После выполнения вашего фактического запроса сохраните результат @@ROWCOUNT в любой переменной, которую вы сможете использовать позже.

EXEC sp_executesql 'SELECT TOP 10 FROM ABX'

SET @TotRecord = @@ROWCOUNT в вашу переменную для последующего использования.

1 голос
/ 01 июня 2011

Имейте в виду, что динамический SQL имеет свою область действия.Любая переменная, объявленная / измененная там, выйдет из области видимости после вашей EXEC или вашей sp_executesql.

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

Возможно, поместите это в свой sqlBottom:

CREATE TABLE ##tempCounter(MyNum int);

EXEC('SELECT @ActualNumberOfResults = COUNT(*) ' + @sqlBody + 
       '; INSERT INTO ##tempCounter(MyNum) VALUES(@ActualNumberOfResults);');

SELECT MyNum FROM ##tempCounter;
0 голосов
/ 10 февраля 2015

Единственная проблема с ответами, которые создают временные таблицы (с использованием «DECLARE @rowcount TABLE» или «CREATE TABLE ## tempCounter (MyNum int)»), заключается в том, что вам приходится читать все затронутые записи с диска вобъем памяти.Если вы ожидаете большое количество записей, это может занять некоторое время.

Так что, если ответ может быть большим, решение "использовать sp_executesql и выходной параметр" является более эффективным ответом.И это похоже на работу.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...