Имя таблицы в качестве переменной
Я пытаюсь выполнить этот запрос:
declare @tablename varchar(50)
set @tablename = 'test'
select * from @tablename
это приводит к следующей ошибке:
Msg 1087, Уровень 16, Состояние 1, Строка 5
необходимо объявить переменную таблицы "@tablename".
Как правильно заполнить имя таблицы динамически?
7 ответов:
имена таблиц и столбцов должны быть статическими, если запрос статичен. Для динамических имен таблиц или столбцов необходимо динамически сгенерировать полный SQL и выполнить его с помощью процедуры sp_executesql.
подробности здесь: проклятие и благословение динамического SQL
измените последнее утверждение на следующее:
EXEC('SELECT * FROM ' + @tablename)вот как я делаю мой в хранимой процедуре. Первый блок объявит переменную и установит имя таблицы на основе имени текущего года и месяца, в этом случае TEST_2012OCTOBER. Затем я проверяю, существует ли он уже в БД, и удаляю, если это так. Затем следующий блок будет использовать инструкцию SELECT INTO для создания таблицы и заполнения ее записями из другой таблицы с параметрами.
--DECLARE TABLE NAME VARIABLE DYNAMICALLY DECLARE @table_name varchar(max) SET @table_name = (SELECT 'TEST_' + DATENAME(YEAR,GETDATE()) + UPPER(DATENAME(MONTH,GETDATE())) ) --DROP THE TABLE IF IT ALREADY EXISTS IF EXISTS(SELECT name FROM sysobjects WHERE name = @table_name AND xtype = 'U') BEGIN EXEC('drop table ' + @table_name) END --CREATES TABLE FROM DYNAMIC VARIABLE AND INSERTS ROWS FROM ANOTHER TABLE EXEC('SELECT * INTO ' + @table_name + ' FROM dbo.MASTER WHERE STATUS_CD = ''A''')
вы не можете использовать имя таблицы для переменной, вы бы вместо этого:
DECLARE @sqlCommand varchar(1000) SET @sqlCommand = 'SELECT * from yourtable' EXEC (@sqlCommand)
немного поздно для ответа, но должен помочь кому-то еще:
CREATE PROCEDURE [dbo].[GetByName] @TableName NVARCHAR(100) AS BEGIN -- SET NOCOUNT ON added to prevent extra result sets from -- interfering with SELECT statements. SET NOCOUNT ON; DECLARE @sSQL nvarchar(500); SELECT @sSQL = N'SELECT * FROM' + QUOTENAME(@TableName); EXEC sp_executesql @sSQL END
вам нужно будет сгенерировать sql динамически:
declare @tablename varchar(50) set @tablename = 'test' declare @sql varchar(500) set @sql = 'select * from ' + @tablename exec (@sql)
использовать
sp_executesqlдля выполнения любого SQL, напримерDECLARE @tbl sysname, @sql nvarchar(4000), @params nvarchar(4000), @count int DECLARE tblcur CURSOR STATIC LOCAL FOR SELECT object_name(id) FROM syscolumns WHERE name = 'LastUpdated' ORDER BY 1 OPEN tblcur WHILE 1 = 1 BEGIN FETCH tblcur INTO @tbl IF @@fetch_status <> 0 BREAK SELECT @sql = N' SELECT @cnt = COUNT(*) FROM dbo.' + quotename(@tbl) + N' WHERE LastUpdated BETWEEN @fromdate AND ' + N' coalesce(@todate, ''99991231'')' SELECT @params = N'@fromdate datetime, ' + N'@todate datetime = NULL, ' + N'@cnt int OUTPUT' EXEC sp_executesql @sql, @params, '20060101', @cnt = @count OUTPUT PRINT @tbl + ': ' + convert(varchar(10), @count) + ' modified rows.' END DEALLOCATE tblcur
Declare @fs_e int, @C_Tables CURSOR, @Table varchar(50) SET @C_Tables = CURSOR FOR select name from sysobjects where OBJECTPROPERTY(id, N'IsUserTable') = 1 AND name like 'TR_%' OPEN @C_Tables FETCH @C_Tables INTO @Table SELECT @fs_e = sdec.fetch_Status FROM sys.dm_exec_cursors(0) as sdec where sdec.name = '@C_Tables' WHILE ( @fs_e <> -1) BEGIN exec('Select * from '+ @Table) FETCH @C_Tables INTO @Table SELECT @fs_e = sdec.fetch_Status FROM sys.dm_exec_cursors(0) as sdec where sdec.name = '@C_Tables' END
Comments