#sql-server #tsql
#sql-сервер #tsql
Вопрос:
Приведен следующий фрагмент (MS SQL):
DECLARE UpdateList CURSOR FOR
SELECT MyColumn FROM MyTable
OPEN UpdateList
Пока ничего особенного. Теперь я хотел бы объявить две переменные, в которые я могу записать имя столбца и таблицы. Следующее, конечно, не сработало бы. Как я могу этого добиться?
DECLARE @TableName nchar(20) = 'MyTable'
DECLARE @ColumnName nchar(20) = 'MyColumn'
DECLARE UpdateList CURSOR FOR
SELECT @ColumnName FROM @TableName
OPEN UpdateList
Спасибо за любые подсказки
sl3dg3
Комментарии:
1. Вам нужно изучить динамический SQL
Ответ №1:
Вам придется использовать динамический SQL — вы не можете использовать параметры в качестве имен таблиц или столбцов. Итак, что-то вроде:
CREATE TABLE #temp (newcol nvarchar(500)) -- Use the type you're getting out of @TableName
DECLARE @TableName nchar(20) = 'MyTable'
DECLARE @ColumnName nchar(20) = 'MyColumn'
EXEC('INSERT INTO #temp SELECT [' @ColumnName '] FROM [' @TableName ']')
DECLARE UpdateList CURSOR FOR
SELECT newcol FROM #temp
OPEN UpdateList
Пожалуйста, имейте в виду проблемы с безопасностью и производительностью, связанные с динамическим SQL — я не знаю, как вы будете заполнять переменные здесь, и в этом может быть определенная опасность.
РЕДАКТИРОВАТЬ: Добавлен полный код.
Комментарии:
1. Спасибо — Это всего лишь скрипт для моего личного использования, поэтому здесь нет угрозы безопасности. Можете ли вы привести мне пример, как использовать это с курсором?
2. Добавлено — пришлось создать временную таблицу, чтобы вы могли выбирать по ней, если вы создадите ее в динамическом SQL, ваш курсор не сможет ее увидеть (если вы не используете глобальные курсоры).
3. Выглядит великолепно — только то, что я по какой-то причине не могу выбрать
newcol
!? В инструкции select (предпоследняя строка) появляется следующая ошибка:Invalid column name 'newcol'.
4. Убедитесь, что имя столбца, который вы создаете в
CREATE TABLE
инструкции, совпадает с именем столбца, который вы выбираете из временной таблицы. При необходимости вы можете проверить схему вашей временной таблицы с помощьюexec tempdb..sp_columns #temp
.5. Мне нужно было удалить #temp, тогда это сработало (кажется, что раньше содержалось неправильное имя). — спасибо
Ответ №2:
Этот код является очень хорошим примером для динамического столбца с курсором, поскольку вы не можете использовать ‘ ‘ в @statement.
ALTER PROCEDURE dbo.spTEST
AS
SET NOCOUNT ON
DECLARE @query NVARCHAR(4000) = N''
DECLARE @inputList NVARCHAR(4000) = ''
DECLARE @field sysname = 'fn'
DECLARE @my_cur CURSOR
EXECUTE SP_EXECUTESQL
N'SET @my_cur = CURSOR FAST_FORWARD FOR SELECT
CASE @field
WHEN ''fn'' then fn
END
FROM dbo.vCard WHERE [fn] LIKE ''%'' @query ''%'';OPEN @my_cur;',
N'@field sysname, @query NVARCHAR(4000), @my_cur CURSOR OUTPUT',
@field = @field,
@query = @query,
@my_cur = @my_cur OUTPUT
FETCH NEXT FROM @my_cur INTO @inputList
WHILE @@FETCH_STATUS = 0
BEGIN
PRINT @inputList
FETCH NEXT FROM @my_cur INTO @inputList
END
RETURN