SQL Server: выполнение динамического / встроенного имени таблицы SQL в EXEC и передача геометрии в качестве параметра геометрии - PullRequest
1 голос
/ 20 января 2012

Я пытаюсь выполнить встроенный оператор SQL в хранимой процедуре. Я работаю с SQL Server 2008.

Проблема в том, что я не могу выполнить первый встроенный оператор (с предложением WHERE). Сбой из-за того, что строка в EXEC(...) создается динамически и все объединенные переменные должны иметь тип varchar.

Ошибка, возникающая при вызове процедуры:

Выражение не булева типа, указанное в контексте, где ожидается состояние, около 'ЗАКАЗАТЬ.

Процедура выглядит так:

CREATE PROCEDURE loadMyRows
  @table_name    nvarchar(50),
  @bounding_box  varchar(8000)
AS
BEGIN
  -- *********************************** COMMENT *********************************
  -- ** This two code lines are correct and will return true (1) or false (0),  **
  -- ** but they doesn't work within inline EXEC(...)                           **
  --DECLARE @bb geometry = geometry::STGeomFromText(@bounding_box, 4326);
  --select TOP(5) wkt.STWithin(@bb) AS 'bool'
  -- *********************************** COMMENT *********************************

IF @bounding_box <> ''
BEGIN
    DECLARE @bb geometry = geometry::STGeomFromText(@bounding_box, 4326);

    EXEC(   
        'SELECT TOP (' + @row_limit + ') * ' +
        'FROM ' + @real_table_name + ' ' +
        'WHERE wkt.STWithin('+@bb+') ' + -- <-- doesn't work :-(
      -- 'WHERE wkt.STWithin(geometry::STGeomFromText('''+@bounding_box+''', 4326)) ' +
      -- ^^ doesn't work, too :-(
        'ORDER BY id ASC '
    );
END
ELSE
BEGIN
    EXEC(
        'SELECT TOP (' + @row_limit + ') * ' +
        'FROM ' + @real_table_name + ' ' +
        'ORDER BY id ASC'
    );
END
END

Ответы [ 2 ]

3 голосов
/ 24 января 2012

Я нашел рабочее решение этой проблемы. MSDN показал мне: http://msdn.microsoft.com/en-US/library/ms175170.aspx. Там написано:

[...] строка исполняется как отдельный пакет.

Это дало мне знать, что если я хочу выполнить динамический оператор с табличной переменной в виде строки, это то же самое, что я бы выполнил запрос без команды EXECUTE, например:

SELECT TOP(@row_limit) *
FROM @real_table_name
WHERE ...
ORDER BY id ASC;

И это, вероятно, не сработает для имени таблицы.

Итак, если я напишу вместо:

DECLARE @sql_statement nvarchar(MAX) = 'SELECT TOP(@limit) * 
                                        FROM ' + @real_table_name + ' 
                                        ORDER BY id ASC';

-- declaration of parameters for above sql                              
DECLARE @sql_param_def nvarchar(MAX) = '@limit int';

EXECUTE sp_executesql @sql_statement, @sql_param_def, @limit = @row_limit;

Тогда это будет работать. Это потому, что я определяю @sql_statement просто как сцепленную строку, которая просто преобразует динамическое имя таблицы во время выполнения в строку с именем реально существующей таблицы. Параметр @limit остается без изменений и остается параметром.

Если мы затем выполним пакет, мы должны только передать значение для параметра @limit, и это работает!

Для параметра геометрии он работает аналогично:

DECLARE @bb geometry = geometry::STGeomFromText(@bounding_box, 4326);
SET @sql_statement = 'SELECT TOP(@limit) * 
                      FROM ' + @real_table_name + ' 
                      WHERE wkt.STWithin(@geobb) = 1 
                      ORDER BY id ASC';
-- NOTE: This ' = 1' must be set to avoid my above described error (STWithin doesn't return a BOOLEAN!!)

-- declaration of parameters for above sql
SET @sql_param_def = '@limit int, @geobb geometry';

EXECUTE sp_executesql @sql_statement, @sql_param_def, @limit = @row_limit, @geobb = @bb;

Надеюсь, это было ясно; -)

0 голосов
/ 05 апреля 2017
create proc usp_insert_Proc_Into_temp
@tempTable nvarchar(10) output
as
begin

 set @tempTable = '##temp' 
 declare @query nvarchar(200)
 --Select statement
 set @query = 'select  1 as A,2 as B, 3 as C into'+ ' '+@tempTable+''
 exec(@query)


end

go


declare @tempTable nvarchar(10)
exec usp_insert_Proc_Into_temp @tempTable output
exec('select *  from' + ' '+ @tempTable+'')

exec ('drop table'+ ' '+@tempTable+'')
...